From f51cb0fa577ed6e581329f99c137f1ca31796db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Mon, 19 Aug 2024 11:52:11 +0200 Subject: [PATCH 01/10] CoinBronKerbosch: Replace pointer arrays by std::vector --- src/CoinBronKerbosch.cpp | 169 +++++++++++---------------------------- src/CoinBronKerbosch.hpp | 33 ++++---- 2 files changed, 63 insertions(+), 139 deletions(-) diff --git a/src/CoinBronKerbosch.cpp b/src/CoinBronKerbosch.cpp index a8b19655..9d2003be 100644 --- a/src/CoinBronKerbosch.cpp +++ b/src/CoinBronKerbosch.cpp @@ -32,17 +32,13 @@ #define BK_EPS 1e-6 static void shuffle_vertices (BKVertex *vertices, size_t n); -static void *xmalloc( const size_t size ); -static void *xcalloc( const size_t elements, const size_t size ); -static void *xrealloc( void *ptr, const size_t size ); bool compareNodes(const BKVertex &u, const BKVertex &v) { return u.fitness >= v.fitness + BK_EPS; } CoinBronKerbosch::CoinBronKerbosch(const CoinConflictGraph *cgraph, const double *weights, PivotingStrategy pivotingStrategy) - : nVertices_(0) - , minWeight_(0.0) + : minWeight_(0.0) , calls_(0) , maxCalls_(std::numeric_limits::max()) , pivotingStrategy_(pivotingStrategy) @@ -52,86 +48,65 @@ CoinBronKerbosch::CoinBronKerbosch(const CoinConflictGraph *cgraph, const double size_t maxDegree = 0; cliques_ = NULL; - mask_ = NULL; - cgBitstring_ = ccgBitstring_ = NULL; - C_ = NULL; - S_ = L_ = P_ = NULL; - nS_ = nL_ = nP_ = NULL; - allIn_ = NULL; - clqWeight_ = NULL; cgraph_ = cgraph; - vertices_ = (BKVertex*)xmalloc(sizeof(BKVertex) * cgSize); + vertices_ = std::vector(); + vertices_.reserve(cgSize); //filling information about vertices for (size_t u = 0; u < cgSize; u++) { const size_t degree = cgraph_->degree(u); if (degree > 0) { - vertices_[nVertices_].idx = u; - vertices_[nVertices_].weight = weights[u]; - vertices_[nVertices_].degree = degree; - nVertices_++; + BKVertex bkv; + bkv.idx = u; + bkv.weight = weights[u]; + bkv.degree = degree; + vertices_.push_back(bkv); maxDegree = std::max(maxDegree, degree); } } - if (nVertices_ == 0) { + if (vertices_.empty()) { return; } computeFitness(weights); - sizeBitVector_ = (nVertices_ / INT_SIZE) + 1; + sizeBitVector_ = (vertices_.size() / INT_SIZE) + 1; //clique set cliques_ = new CoinCliqueList(4096, 32768); clqWeightCap_ = 4096; - clqWeight_ = (double*)xmalloc(sizeof(double) * clqWeightCap_); + clqWeight_ = std::vector(clqWeightCap_); nC_ = 0; weightC_ = 0.0; - C_ = (size_t*)xmalloc(sizeof(size_t) * (maxDegree + 1)); + C_ = std::vector(maxDegree + 1); - allIn_ = (size_t*)xcalloc(sizeBitVector_, sizeof(size_t)); + allIn_ = std::vector(sizeBitVector_); - nS_ = (size_t*)xcalloc((maxDegree + 2) * 3, sizeof(size_t)); - nL_ = nS_ + maxDegree + 2; - nP_ = nL_ + maxDegree + 2; + nS_ = std::vector(maxDegree + 2); + nP_ = std::vector(maxDegree + 2); - S_ = (size_t**) xmalloc(sizeof(size_t*) * (maxDegree + 2) * 3); - L_ = S_ + maxDegree + 2; - P_ = L_ + maxDegree + 2; + S_ = std::vector >(maxDegree + 2, std::vector(sizeBitVector_)); + L_ = std::vector >(maxDegree + 2, std::vector(sizeBitVector_)); + P_ = std::vector >(maxDegree + 2, std::vector(sizeBitVector_)); - S_[0] = (size_t*)xcalloc((maxDegree + 2) * sizeBitVector_ * 3, sizeof(size_t)); - L_[0] = S_[0] + ((maxDegree + 2) * sizeBitVector_); - P_[0] = L_[0] + ((maxDegree + 2) * sizeBitVector_); - for (size_t i = 1; i < maxDegree + 2; i++) { - S_[i] = S_[i-1] + sizeBitVector_; - L_[i] = L_[i-1] + sizeBitVector_; - P_[i] = P_[i-1] + sizeBitVector_; - } - - mask_ = (size_t*)xmalloc(sizeof(size_t) * INT_SIZE); + mask_ = std::vector(INT_SIZE); mask_[0] = 1; for (size_t h = 1; h < INT_SIZE; h++) { mask_[h] = mask_[h - 1] << 1U; } - cgBitstring_ = (size_t**)xmalloc(sizeof(size_t*) * nVertices_ * 2); - ccgBitstring_ = cgBitstring_ + nVertices_; - cgBitstring_[0] = (size_t*)xcalloc(nVertices_ * sizeBitVector_ * 2, sizeof(size_t)); - ccgBitstring_[0] = cgBitstring_[0] + (nVertices_ * sizeBitVector_); - for (size_t i = 1; i < nVertices_; i++) { - cgBitstring_[i] = cgBitstring_[i-1] + sizeBitVector_; - ccgBitstring_[i] = ccgBitstring_[i-1] + sizeBitVector_; - } + cgBitstring_ = std::vector >(vertices_.size(), std::vector(sizeBitVector_)); + ccgBitstring_ = std::vector >(vertices_.size(), std::vector(sizeBitVector_)); - for(size_t u = 0; u < nVertices_; u++) { + for(size_t u = 0; u < vertices_.size(); u++) { BKVertex &vertexU = vertices_[u]; allIn_[u / INT_SIZE] |= mask_[u % INT_SIZE]; ccgBitstring_[u][u / INT_SIZE] |= mask_[u % INT_SIZE]; - for(size_t v = u + 1; v < nVertices_; v++) { + for(size_t v = u + 1; v < vertices_.size(); v++) { BKVertex &vertexV = vertices_[v]; if (cgraph_->conflicting(vertexU.idx, vertexV.idx)) { @@ -147,18 +122,7 @@ CoinBronKerbosch::CoinBronKerbosch(const CoinConflictGraph *cgraph, const double CoinBronKerbosch::~CoinBronKerbosch() { - free(vertices_); - - if (nVertices_ > 0) { - free(mask_); - free(cgBitstring_[0]); - free(cgBitstring_); - free(allIn_); - free(C_); - free(S_[0]); - free(S_); - free(nS_); - free(clqWeight_); + if (!vertices_.empty()) { delete cliques_; } } @@ -196,14 +160,14 @@ void CoinBronKerbosch::bronKerbosch(size_t depth) { //checking memory if (nCliques + 1 > clqWeightCap_) { clqWeightCap_ *= 2; - clqWeight_ = (double*) xrealloc(clqWeight_, sizeof(double)*(clqWeightCap_) ); + clqWeight_.resize(clqWeightCap_); } //maximal clique above a threshold found - cliques_->addClique(nC_, C_); + cliques_->addClique(nC_, C_.data()); clqWeight_[nCliques] = weightC_; #ifdef DEBUGCG - CoinCliqueList::validateClique(cgraph_, C_, nC_); + CoinCliqueList::validateClique(cgraph_, C_.data(), nC_); #endif return; @@ -223,13 +187,8 @@ void CoinBronKerbosch::bronKerbosch(size_t depth) { if(weightC_ + wP >= minWeight_) { //L = P \ N(u) - nL_[depth] = 0; for(size_t i = 0; i < sizeBitVector_; i++) { L_[depth][i] = P_[depth][i] & ccgBitstring_[u][i]; - - if(L_[depth][i]) { - nL_[depth]++; - } } //for each v in L @@ -290,12 +249,12 @@ void CoinBronKerbosch::bronKerbosch(size_t depth) { } void CoinBronKerbosch::findCliques() { - if (nVertices_ == 0) { + if (vertices_.empty()) { return; } - nP_[0] = nVertices_; - for(size_t i = 0; i < nVertices_; i++) { + nP_[0] = vertices_.size(); + for(size_t i = 0; i < vertices_.size(); i++) { P_[0][i / INT_SIZE] |= mask_[i % INT_SIZE]; } @@ -355,65 +314,61 @@ void CoinBronKerbosch::computeFitness(const double *weights) { //do nothing break; case PivotingStrategy::Random: { - shuffle_vertices(vertices_, nVertices_); + shuffle_vertices(vertices_.data(), vertices_.size()); break; } case PivotingStrategy::Degree: { - for (size_t u = 0; u < nVertices_; u++) { + for (size_t u = 0; u < vertices_.size(); u++) { const size_t uIdx = vertices_[u].idx; vertices_[u].fitness = cgraph_->degree(uIdx); } - std::sort(vertices_, vertices_ + nVertices_, compareNodes); + std::sort(vertices_.begin(), vertices_.end(), compareNodes); break; } case PivotingStrategy::Weight: { - for (size_t u = 0; u < nVertices_; u++) { + for (size_t u = 0; u < vertices_.size(); u++) { const size_t uIdx = vertices_[u].idx; vertices_[u].fitness = weights[uIdx]; } - std::sort(vertices_, vertices_ + nVertices_, compareNodes); + std::sort(vertices_.begin(), vertices_.end(), compareNodes); break; } case PivotingStrategy::ModifiedDegree: { - for (size_t u = 0; u < nVertices_; u++) { + for (size_t u = 0; u < vertices_.size(); u++) { const size_t uIdx = vertices_[u].idx; vertices_[u].fitness = cgraph_->modifiedDegree(uIdx); } - std::sort(vertices_, vertices_ + nVertices_, compareNodes); + std::sort(vertices_.begin(), vertices_.end(), compareNodes); break; } case PivotingStrategy::ModifiedWeight: { - size_t *neighs = (size_t*)xmalloc(sizeof(size_t) * cgraph_->size()); - char *iv = (char*)xcalloc(cgraph_->size(), sizeof(char)); - for (size_t u = 0; u < nVertices_; u++) { + std::vector neighs = std::vector(cgraph_->size()); + std::vector iv = std::vector(cgraph_->size()); + for (size_t u = 0; u < vertices_.size(); u++) { const size_t uIdx = vertices_[u].idx; - const std::pair rescg = cgraph_->conflictingNodes(uIdx, neighs, iv); + const std::pair rescg = cgraph_->conflictingNodes(uIdx, neighs.data(), iv.data()); vertices_[u].fitness = weights[uIdx]; for (size_t v = 0; v < rescg.first; v++) { const size_t vIdx = rescg.second[v]; vertices_[u].fitness += weights[vIdx]; } } - free(neighs); - free(iv); - std::sort(vertices_, vertices_ + nVertices_, compareNodes); + std::sort(vertices_.begin(), vertices_.end(), compareNodes); break; } case PivotingStrategy::ModifiedDegreeWeight: { - size_t *neighs = (size_t*)xmalloc(sizeof(size_t) * cgraph_->size()); - char *iv = (char*)xcalloc(cgraph_->size(), sizeof(char)); - for (size_t u = 0; u < nVertices_; u++) { + std::vector neighs = std::vector(cgraph_->size()); + std::vector iv = std::vector(cgraph_->size()); + for (size_t u = 0; u < vertices_.size(); u++) { const size_t uIdx = vertices_[u].idx; - const std::pair rescg = cgraph_->conflictingNodes(uIdx, neighs, iv); + const std::pair rescg = cgraph_->conflictingNodes(uIdx, neighs.data(), iv.data()); vertices_[u].fitness = weights[uIdx] + cgraph_->modifiedDegree(uIdx); for (size_t v = 0; v < rescg.first; v++) { const size_t vIdx = rescg.second[v]; vertices_[u].fitness += (weights[vIdx] + cgraph_->modifiedDegree(vIdx)); } } - free(neighs); - free(iv); - std::sort(vertices_, vertices_ + nVertices_, compareNodes); + std::sort(vertices_.begin(), vertices_.end(), compareNodes); break; } default: @@ -422,36 +377,6 @@ void CoinBronKerbosch::computeFitness(const double *weights) { } } -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 *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; -} - -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 shuffle_vertices (BKVertex *vertices, size_t n) { if (n <= 1) { return; diff --git a/src/CoinBronKerbosch.hpp b/src/CoinBronKerbosch.hpp index ace75fbd..e8e7809d 100644 --- a/src/CoinBronKerbosch.hpp +++ b/src/CoinBronKerbosch.hpp @@ -21,6 +21,7 @@ #define COINBRONKERBOSCH_HPP #include +#include #include "CoinUtilsConfig.h" class CoinConflictGraph; @@ -162,12 +163,7 @@ class COINUTILSLIB_EXPORT CoinBronKerbosch { /** * Array of vertices **/ - BKVertex *vertices_; - - /** - * Number of vertices of the conflict graph - **/ - size_t nVertices_; + std::vector vertices_; /** * Size of each bit vector @@ -177,22 +173,23 @@ class COINUTILSLIB_EXPORT CoinBronKerbosch { /** * Bit mask **/ - size_t *mask_; + std::vector mask_; /** * Conflict graph and its complement represented by bit vectors **/ - size_t **cgBitstring_, **ccgBitstring_; + std::vector > cgBitstring_, ccgBitstring_; /** * Bitstring with all vertices **/ - size_t *allIn_; + std::vector allIn_; /** * Set C of vertices that are part of the current clique **/ - size_t *C_, nC_; + std::vector C_; + size_t nC_; /** * Sum of the weights of the vertices in C @@ -201,27 +198,29 @@ class COINUTILSLIB_EXPORT CoinBronKerbosch { /** * Set of the candidate vertices to enter in C - * Contain a pointer for each depth of BK algorithm. + * Contain a vector for each depth of BK algorithm. **/ - size_t **P_, *nP_; + std::vector > P_; + std::vector nP_; /** * Set of all vertices that have already been considered - * in earlier steps by BK. Contain a pointer for each + * in earlier steps by BK. Contain a vector for each * depth of BK algorithm. **/ - size_t **S_, *nS_; + std::vector > S_; + std::vector nS_; /** * Set of vertices P excluding the neighbors of a vertex v. - * Contain a pointer for each depth of BK algorithm. + * Contain a vector for each depth of BK algorithm. **/ - size_t **L_, *nL_; + std::vector > L_; /** * Array that stores the weights of each clique found by BK **/ - double *clqWeight_; + std::vector clqWeight_; /** * Current capacity of array clqWeight_ From 776ea49d7dc2080720701c9f795cf61e7c4c82dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Mon, 19 Aug 2024 17:26:23 +0200 Subject: [PATCH 02/10] CoinCliqueExtender: Replace pointer arrays by std::vector --- src/CoinCliqueExtender.cpp | 65 ++++++++++---------------------------- src/CoinCliqueExtender.hpp | 13 +++++--- 2 files changed, 25 insertions(+), 53 deletions(-) diff --git a/src/CoinCliqueExtender.cpp b/src/CoinCliqueExtender.cpp index d7a4cad7..c81cddca 100644 --- a/src/CoinCliqueExtender.cpp +++ b/src/CoinCliqueExtender.cpp @@ -30,8 +30,6 @@ #define CLQEXT_EPS 1e-6 static void shuffle_array(size_t *arr, size_t n); -static void *xmalloc( size_t size ); -static void *xcalloc( const size_t elements, const size_t size ); struct CompareCost { explicit CompareCost(const double *costs) { this->costs_ = costs; } @@ -54,12 +52,11 @@ CoinCliqueExtender::CoinCliqueExtender(const CoinConflictGraph *cgraph, size_t e cgraph_ = cgraph; extendedCliques_ = new CoinCliqueList(4096, 32768); nCandidates_ = nNewClique_ = 0; - candidates_ = (size_t*)xmalloc(sizeof(size_t) * cgSize); - newClique_ = (size_t*)xmalloc(sizeof(size_t) * cgSize); - costs_ = NULL; + candidates_ = std::vector(cgSize); + newClique_ = std::vector(cgSize); - iv_ = (char*)xcalloc(cgSize, sizeof(char)); - iv2_ = (char*)xcalloc(cgSize, sizeof(char)); + iv_ = std::vector(cgSize); + iv2_ = std::vector(cgSize); extMethod_ = extMethod; rc_ = rc; @@ -79,7 +76,7 @@ CoinCliqueExtender::CoinCliqueExtender(const CoinConflictGraph *cgraph, size_t e break; } case 2: { //max degree extension - costs_ = (double *) xmalloc(sizeof(double) * cgSize); + costs_ = std::vector(cgSize); for (size_t i = 0; i < cgSize; i++) { #ifdef DEBUGCG assert(cgraph_->degree(i) < cgSize); @@ -90,7 +87,7 @@ CoinCliqueExtender::CoinCliqueExtender(const CoinConflictGraph *cgraph, size_t e break; case 3: {//modified degree extension double maxModDegree = 0.0; - costs_ = (double *) xmalloc(sizeof(double) * cgSize); + costs_ = std::vector(cgSize); for (size_t i = 0; i < cgSize; i++) { costs_[i] = cgraph_->modifiedDegree(i); maxModDegree = std::max(maxModDegree, costs_[i]); @@ -108,7 +105,7 @@ CoinCliqueExtender::CoinCliqueExtender(const CoinConflictGraph *cgraph, size_t e break; } case 5: { //reduced cost + modified degree - costs_ = (double *) xmalloc(sizeof(double) * cgSize); + costs_ = std::vector(cgSize); double minRCost, maxRCost; size_t minMDegree, maxMDegree; minRCost = maxRCost = rc[0]; @@ -140,14 +137,6 @@ CoinCliqueExtender::CoinCliqueExtender(const CoinConflictGraph *cgraph, size_t e CoinCliqueExtender::~CoinCliqueExtender() { delete extendedCliques_; - free(candidates_); - free(newClique_); - free(iv_); - free(iv2_); - - if (costs_) { - free(costs_); - } } bool CoinCliqueExtender::randomExtension(const size_t *clqIdxs, const size_t clqSize) { @@ -161,7 +150,7 @@ bool CoinCliqueExtender::randomExtension(const size_t *clqIdxs, const size_t clq return false; } - shuffle_array(candidates_, nCandidates_); + shuffle_array(candidates_.data(), nCandidates_); nCandidates_ = std::min(nCandidates_, maxCandidates_); for (size_t i = 0; i < nCandidates_; i++) { @@ -184,10 +173,10 @@ bool CoinCliqueExtender::randomExtension(const size_t *clqIdxs, const size_t clq } #ifdef DEBUGCG - CoinCliqueList::validateClique(cgraph_, newClique_, nNewClique_); + CoinCliqueList::validateClique(cgraph_, newClique_.data(), nNewClique_); #endif - extendedCliques_->addClique(nNewClique_, newClique_); + extendedCliques_->addClique(nNewClique_, newClique_.data()); return true; } @@ -205,7 +194,7 @@ bool CoinCliqueExtender::greedySelection(const size_t *clqIdxs, const size_t clq const size_t n = nCandidates_; nCandidates_ = std::min(nCandidates_, maxCandidates_); - std::partial_sort(candidates_, candidates_ + nCandidates_, candidates_ + n, CompareCost(costs)); + std::partial_sort(candidates_.begin(), candidates_.begin() + nCandidates_, candidates_.begin() + n, CompareCost(costs)); for (size_t i = 0; i < nCandidates_; i++) { /* need to have conflict with all nodes in clique */ @@ -227,10 +216,10 @@ bool CoinCliqueExtender::greedySelection(const size_t *clqIdxs, const size_t clq } #ifdef DEBUGCG - CoinCliqueList::validateClique(cgraph_, newClique_, nNewClique_); + CoinCliqueList::validateClique(cgraph_, newClique_.data(), nNewClique_); #endif - extendedCliques_->addClique(nNewClique_, newClique_); + extendedCliques_->addClique(nNewClique_, newClique_.data()); return true; } @@ -261,16 +250,16 @@ bool CoinCliqueExtender::extendClique(const size_t *clqIdxs, const size_t clqSiz result = randomExtension(clqIdxs, clqSize); break; case 2: //max degree - result = greedySelection(clqIdxs, clqSize, costs_); + result = greedySelection(clqIdxs, clqSize, costs_.data()); break; case 3: //modified degree - result = greedySelection(clqIdxs, clqSize, costs_); + result = greedySelection(clqIdxs, clqSize, costs_.data()); break; case 4: //priority greedy (reduced cost) result = greedySelection(clqIdxs, clqSize, rc_); break; case 5: //reduced cost + modified degree - result = greedySelection(clqIdxs, clqSize, costs_); + result = greedySelection(clqIdxs, clqSize, costs_.data()); break; default: fprintf(stderr, "Invalid option %lu\n", extMethod_); @@ -301,7 +290,7 @@ void CoinCliqueExtender::fillCandidates(const size_t *clqIdxs, const size_t clqS iv_[clqIdx] = 1; } - const std::pair rescg = cgraph_->conflictingNodes(nodeSD, candidates_, iv2_); + const std::pair rescg = cgraph_->conflictingNodes(nodeSD, candidates_.data(), iv2_.data()); for (size_t i = 0; i < rescg.first; i++) { const size_t node = rescg.second[i]; @@ -360,26 +349,6 @@ size_t CoinCliqueExtender::getCliqueSize(const size_t i) const { return extendedCliques_->cliqueSize(i); } -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 *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; -} - static void shuffle_array (size_t *arr, size_t n) { if (n <= 1) { return; diff --git a/src/CoinCliqueExtender.hpp b/src/CoinCliqueExtender.hpp index 2dce7588..058c5685 100644 --- a/src/CoinCliqueExtender.hpp +++ b/src/CoinCliqueExtender.hpp @@ -18,6 +18,7 @@ #ifndef COINCLIQUEEXTENDER_HPP #define COINCLIQUEEXTENDER_HPP +#include class CoinCliqueList; class CoinConflictGraph; @@ -130,27 +131,29 @@ class COINUTILSLIB_EXPORT CoinCliqueExtender { size_t maxCandidates_; /** - * Candidates list + * Candidates list, used to temporarily store candidate vertices. **/ - size_t *candidates_, nCandidates_; //used to temporarily store candidate vertices. + std::vector candidates_; + size_t nCandidates_; /** * Auxiliary array used to temporarily * store a new extended clique. **/ - size_t *newClique_, nNewClique_; + std::vector newClique_; + size_t nNewClique_; /** * Array containing the cost of each vertex, * computed according to the clique extension method. * Used to greedy select the candidates to enter a clique. **/ - double *costs_; + std::vector costs_; /** * Auxiliary incidence vectors **/ - char *iv_, *iv2_; + std::vector iv_, iv2_; /** * Array containing the reduced cost associated From 96ef23e707b71bd14234726eb5f8a6150213bac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Mon, 19 Aug 2024 17:35:01 +0200 Subject: [PATCH 03/10] CoinConflictGraph: Replace pointer arrays by std::vector --- src/CoinConflictGraph.cpp | 39 +++++---------------------------------- 1 file changed, 5 insertions(+), 34 deletions(-) diff --git a/src/CoinConflictGraph.cpp b/src/CoinConflictGraph.cpp index 49baf697..43494018 100644 --- a/src/CoinConflictGraph.cpp +++ b/src/CoinConflictGraph.cpp @@ -32,10 +32,6 @@ size_t CoinConflictGraph::minClqRow_ = 256; -static void *xmalloc(const size_t size); - -static void *xcalloc(const size_t elements, const size_t size); - CoinConflictGraph::CoinConflictGraph(size_t _size) { iniCoinConflictGraph(_size); } @@ -88,33 +84,13 @@ bool CoinConflictGraph::conflicting(size_t n1, size_t n2) const { return conflictInCliques(n1, n2); } -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 *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; -} - void CoinConflictGraph::recomputeDegree() { double start = CoinCpuTime(); this->nConflicts_ = 0; minDegree_ = std::numeric_limits::max(); maxDegree_ = std::numeric_limits::min(); - char *iv = (char *) xcalloc(size_, sizeof(char)); + std::vector iv = std::vector(size_); for (size_t i = 0; (i < size_); ++i) { const size_t ndc = nDirectConflicts(i); @@ -158,7 +134,6 @@ void CoinConflictGraph::recomputeDegree() { nConflicts_ += dg; } - free(iv); density_ = (double) nConflicts_ / maxConflicts_; double secs = CoinCpuTime() - start; if (secs>1.0) @@ -170,7 +145,7 @@ void CoinConflictGraph::computeModifiedDegree() { return; } - char *iv = (char *) xcalloc(size_, sizeof(char)); + std::vector iv = std::vector(size_); for (size_t i = 0; i < size_; i++) { const size_t ndc = nDirectConflicts(i); @@ -211,7 +186,6 @@ void CoinConflictGraph::computeModifiedDegree() { } updateMDegree = false; - free(iv); } std::pair CoinConflictGraph::conflictingNodes(size_t node, size_t *temp, char *iv) const { @@ -333,14 +307,14 @@ void CoinConflictGraph::printSummary() const { } if (numEdges) { - size_t *neighs = (size_t *) xmalloc(sizeof(size_t) * size_); - char *iv = (char *) xcalloc(size_, sizeof(char)); + std::vector neighs = std::vector(size_); + std::vector iv = std::vector(size_); avgDegree = ((double) numEdges) / ((double) numVertices); density = (2.0 * ((double) numEdges)) / (((double) numVertices) * (((double) numVertices) - 1.0)); for (size_t i = 0; i < size_; i++) { - const std::pair rescg = conflictingNodes(i, neighs, iv); + const std::pair rescg = conflictingNodes(i, neighs.data(), iv.data()); for (size_t j = 0; j < rescg.first; j++) { const size_t vertexNeighbor = rescg.second[j]; @@ -364,9 +338,6 @@ void CoinConflictGraph::printSummary() const { confsCompVars = (confsCompVars / ((double)numEdges)); mixedConfs = (mixedConfs / ((double)numEdges)); trivialConflicts = (trivialConflicts / ((double)numEdges)); - - free(neighs); - free(iv); } printf("%ld;%ld;%lf;%ld;%ld;%lf;%lf;%lf;%lf;%lf;", numVertices, numEdges, density, minDegree, maxDegree, From 5927ae6751c27bba0edab074808feb3276345658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Mon, 19 Aug 2024 18:08:41 +0200 Subject: [PATCH 04/10] CoinOddWheelSeparator: Replace pointer arrays by std::vector --- src/CoinOddWheelSeparator.cpp | 188 ++++++++-------------------------- src/CoinOddWheelSeparator.hpp | 48 +++------ 2 files changed, 59 insertions(+), 177 deletions(-) diff --git a/src/CoinOddWheelSeparator.cpp b/src/CoinOddWheelSeparator.cpp index 715d0655..91bfb9f5 100644 --- a/src/CoinOddWheelSeparator.cpp +++ b/src/CoinOddWheelSeparator.cpp @@ -34,10 +34,6 @@ #define ODDWHEEL_SEP_DEF_MIN_VIOL 0.02 #define ODDWHEEL_SEP_DEF_MAX_WHEEL_CENTERS ((size_t)256) -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 CompareCost { explicit CompareCost(const double *costs) { this->costs_ = costs; } @@ -59,21 +55,21 @@ CoinOddWheelSeparator::CoinOddWheelSeparator(const CoinConflictGraph *cgraph, co x_ = x; rc_ = rc; icaCount_ = 0; - icaIdx_ = (size_t*)xmalloc(sizeof(size_t) * cgSize); - icaActivity_ = (double*)xmalloc(sizeof(double) * cgSize); + icaIdx_ = std::vector(cgSize); + icaActivity_ = std::vector(cgSize); fillActiveColumns(); - numOH_ = 0; extMethod_ = extMethod; + spf_ = NULL; if (icaCount_ > 4) { - spArcStart_ = (size_t *) xmalloc(sizeof(size_t) * ((icaCount_ * 2) + 1)); + spArcStart_ = std::vector((icaCount_ * 2) + 1); spArcCap_ = icaCount_ * 2; - spArcTo_ = (size_t *) xmalloc(sizeof(size_t) * spArcCap_); - spArcDist_ = (double*) xmalloc(sizeof(double) * spArcCap_); + spArcTo_ = std::vector(spArcCap_); + spArcDist_ = std::vector(spArcCap_); - tmp_ = (size_t *) xmalloc(sizeof(size_t) * (cgSize + 1)); + tmp_ = std::vector(cgSize + 1); - costs_ = (double *) xmalloc(sizeof(double) * cgSize); + costs_ = std::vector(cgSize); for (size_t i = 0; i < cgSize; i++) { if (x_[i] >= ODDWHEEL_SEP_DEF_EPS) { costs_[i] = (x_[i] * 1000.0); @@ -84,67 +80,19 @@ CoinOddWheelSeparator::CoinOddWheelSeparator(const CoinConflictGraph *cgraph, co } } - iv_ = (char *) xcalloc(cgSize, sizeof(char)); - iv2_ = (char *) xcalloc(cgSize, sizeof(char)); - - spf_ = NULL; - - ohStart_ = (size_t*)xcalloc(icaCount_ + 1, sizeof(size_t)); - wcStart_ = (size_t*)xcalloc(icaCount_ + 1, sizeof(size_t)); - capOHIdxs_ = icaCount_ * 2; - ohIdxs_ = (size_t*)xmalloc(sizeof(size_t) * capOHIdxs_); - capWCIdx_ = icaCount_ * 2; - wcIdxs_ = (size_t*)xmalloc(sizeof(size_t) * capWCIdx_); - } else { - spArcStart_ = spArcTo_ = tmp_ = NULL; - spArcDist_ = NULL; - costs_ = NULL; - iv_ = iv2_ = NULL; - spf_ = NULL; - ohStart_ = wcStart_ = ohIdxs_ = wcIdxs_ = NULL; + iv_ = std::vector(cgSize); + iv2_ = std::vector(cgSize); + + ohIdxs_ = std::vector >(); + ohIdxs_.reserve(icaCount_); + wcIdxs_ = std::vector >(icaCount_); } } CoinOddWheelSeparator::~CoinOddWheelSeparator() { - free(icaIdx_); - free(icaActivity_); - - if (spArcStart_) { - free(spArcStart_); - } - if (spArcTo_) { - free(spArcTo_); - } - if (spArcDist_) { - free(spArcDist_); - } - if (tmp_) { - free(tmp_); - } - if (costs_) { - free(costs_); - } - if (iv_) { - free(iv_); - } - if (iv2_) { - free(iv2_); - } if (spf_) { delete spf_; } - if (ohStart_) { - free(ohStart_); - } - if (ohIdxs_) { - free(ohIdxs_); - } - if (wcIdxs_) { - free(wcIdxs_); - } - if (wcStart_) { - free(wcStart_); - } } void CoinOddWheelSeparator::searchOddWheels() { @@ -160,7 +108,7 @@ void CoinOddWheelSeparator::searchOddWheels() { if (extMethod_ > 0) { //try to insert a wheel center - for (size_t i = 0; i < numOH_; i++) { + for (size_t i = 0; i < ohIdxs_.size(); i++) { searchWheelCenter(i); } } @@ -213,8 +161,8 @@ void CoinOddWheelSeparator::prepareGraph() { if (cgraph_->conflicting(idx1, idx2)) { if(idxArc + 1 > spArcCap_) { spArcCap_ *= 2; - spArcTo_ = (size_t*)xrealloc(spArcTo_, sizeof(size_t) * spArcCap_); - spArcDist_ = (double*)xrealloc(spArcDist_, sizeof(double) * spArcCap_); + spArcTo_.resize(spArcCap_); + spArcDist_.resize(spArcCap_); } spArcTo_[idxArc] = icaCount_ + i2; spArcDist_[idxArc] = icaActivity_[i2]; @@ -236,8 +184,8 @@ void CoinOddWheelSeparator::prepareGraph() { if(idxArc + 1 > spArcCap_) { spArcCap_ *= 2; - spArcTo_ = (size_t*)xrealloc(spArcTo_, sizeof(size_t) * spArcCap_); - spArcDist_ = (double*)xrealloc(spArcDist_, sizeof(double) * spArcCap_); + spArcTo_.resize(spArcCap_); + spArcDist_.resize(spArcCap_); } spArcTo_[idxArc] = arcTo; @@ -247,14 +195,14 @@ void CoinOddWheelSeparator::prepareGraph() { } spArcStart_[icaCount_ * 2] = idxArc; - spf_ = new CoinShortestPath(nodes, idxArc, spArcStart_, spArcTo_, spArcDist_); + spf_ = new CoinShortestPath(nodes, idxArc, spArcStart_.data(), spArcTo_.data(), spArcDist_.data()); } void CoinOddWheelSeparator::findOddHolesWithNode(size_t node) { const size_t dest = icaCount_ + node; spf_->find(node, dest); - size_t oddSize = spf_->path(dest, tmp_); + size_t oddSize = spf_->path(dest, tmp_.data()); #ifdef DEBUGCG assert(oddSize > 0); @@ -308,43 +256,33 @@ void CoinOddWheelSeparator::findOddHolesWithNode(size_t node) { addOddHole(oddSize, tmp_); } -bool CoinOddWheelSeparator::addOddHole(size_t nz, const size_t *idxs) { +bool CoinOddWheelSeparator::addOddHole(size_t nz, const std::vector &idxs) { // checking for repeated entries if (alreadyInserted(nz, idxs)) { return false; } - // checking memory - if (ohStart_[numOH_] + nz > capOHIdxs_) { - capOHIdxs_ = std::max(ohStart_[numOH_] + nz, capOHIdxs_ * 2); - ohIdxs_ = (size_t*)xrealloc(ohIdxs_, sizeof(size_t) * capOHIdxs_); - } - - // inserting - memcpy(ohIdxs_ + ohStart_[numOH_], idxs, sizeof(size_t) * nz); - numOH_++; - ohStart_[numOH_] = ohStart_[numOH_ - 1] + nz; + ohIdxs_.push_back(idxs); return true; } -bool CoinOddWheelSeparator::alreadyInserted(size_t nz, const size_t *idxs) { +bool CoinOddWheelSeparator::alreadyInserted(size_t nz, const std::vector &idxs) { bool repeated = false; for (size_t i = 0; i < nz; i++) { iv_[idxs[i]] = 1; } - for (size_t idxOH = 0; idxOH < numOH_; idxOH++) { + for (size_t idxOH = 0; idxOH < ohIdxs_.size(); idxOH++) { // checking size - const size_t otherSize = ohStart_[idxOH + 1] - ohStart_[idxOH]; - if (nz != otherSize) { + if (nz != ohIdxs_[idxOH].size()) { continue; } // checking indexes bool isEqual = true; - const size_t *ohIdx = ohIdxs_ + ohStart_[idxOH]; + const size_t *ohIdx = ohIdxs_[idxOH].data(); for (size_t j = 0; j < nz; j++) { if (!iv_[ohIdx[j]]) { isEqual = false; @@ -367,12 +305,11 @@ bool CoinOddWheelSeparator::alreadyInserted(size_t nz, const size_t *idxs) { void CoinOddWheelSeparator::searchWheelCenter(size_t idxOH) { #ifdef DEBUGCG - assert(idxOH < numOH_); - assert(ohStart_[idxOH + 1] >= ohStart_[idxOH]); + assert(idxOH < ohIdxs_.size()); #endif - const size_t *ohIdxs = ohIdxs_ + ohStart_[idxOH]; - const size_t ohSize = ohStart_[idxOH + 1] - ohStart_[idxOH]; + const size_t *ohIdxs = ohIdxs_[idxOH].data(); + const size_t ohSize = ohIdxs_[idxOH].size(); #ifdef DEBUGCG assert(ohSize <= cgraph_->size()); @@ -392,7 +329,7 @@ void CoinOddWheelSeparator::searchWheelCenter(size_t idxOH) { } // generating candidates - const std::pair rescg = cgraph_->conflictingNodes(nodeSD, tmp_, iv2_); + const std::pair rescg = cgraph_->conflictingNodes(nodeSD, tmp_.data(), iv2_.data()); size_t numCandidates = 0; for (size_t i = 0; i < rescg.first; i++) { const size_t node = rescg.second[i]; @@ -423,9 +360,7 @@ void CoinOddWheelSeparator::searchWheelCenter(size_t idxOH) { } } - if (numCandidates == 0) { - wcStart_[idxOH + 1] = wcStart_[idxOH]; - } else { + if (numCandidates != 0) { size_t sizeWC = 0; if (extMethod_ == 1) { //wheel center with only one variable @@ -442,7 +377,7 @@ void CoinOddWheelSeparator::searchWheelCenter(size_t idxOH) { assert(extMethod_ == 2); const size_t n = numCandidates; numCandidates = std::min(numCandidates, ODDWHEEL_SEP_DEF_MAX_WHEEL_CENTERS); - std::partial_sort(tmp_, tmp_ + numCandidates, tmp_ + n, CompareCost(costs_)); + std::partial_sort(tmp_.begin(), tmp_.begin() + numCandidates, tmp_.begin() + n, CompareCost(costs_.data())); for (size_t i = 0; i < numCandidates; i++) { /* need to have conflict with all nodes in clique */ @@ -460,13 +395,7 @@ void CoinOddWheelSeparator::searchWheelCenter(size_t idxOH) { } } - // checking memory - if (wcStart_[idxOH] + sizeWC > capWCIdx_) { - capWCIdx_ = std::max(capWCIdx_ * 2, wcStart_[idxOH] + sizeWC); - wcIdxs_ = (size_t*)xrealloc(wcIdxs_, sizeof(size_t) * capWCIdx_); - } - memcpy(wcIdxs_ + wcStart_[idxOH], tmp_, sizeof(size_t) * sizeWC); - wcStart_[idxOH + 1] = wcStart_[idxOH] + sizeWC; + wcIdxs_[idxOH] = std::vector(tmp_.begin(), tmp_.begin() + sizeWC); } // clearing iv @@ -477,69 +406,40 @@ void CoinOddWheelSeparator::searchWheelCenter(size_t idxOH) { const size_t* CoinOddWheelSeparator::oddHole(size_t idxOH) const { #ifdef DEBUGCG - assert(idxOH < numOH_); + assert(idxOH < ohIdxs_.size()); #endif - return ohIdxs_ + ohStart_[idxOH]; + return ohIdxs_[idxOH].data(); } size_t CoinOddWheelSeparator::oddHoleSize(size_t idxOH) const { #ifdef DEBUGCG - assert(idxOH < numOH_); + assert(idxOH < ohIdxs_.size()); #endif - return ohStart_[idxOH + 1] - ohStart_[idxOH]; + return ohIdxs_[idxOH].size(); } double CoinOddWheelSeparator::oddWheelRHS(size_t idxOH) const { #ifdef DEBUGCG - assert(idxOH < numOH_); + assert(idxOH < ohIdxs_.size()); #endif - return floor(((double)ohStart_[idxOH + 1] - ohStart_[idxOH]) / 2.0); + return floor(static_cast(ohIdxs_[idxOH].size()) / 2.0); } const size_t* CoinOddWheelSeparator::wheelCenter(const size_t idxOH) const { #ifdef DEBUGCG - assert(idxOH < numOH_); + assert(idxOH < ohIdxs_.size()); #endif - return wcIdxs_ + wcStart_[idxOH]; + return wcIdxs_[idxOH].data(); } size_t CoinOddWheelSeparator::wheelCenterSize(const size_t idxOH) const { #ifdef DEBUGCG - assert(idxOH < numOH_); + assert(idxOH < ohIdxs_.size()); #endif - return wcStart_[idxOH + 1] - wcStart_[idxOH]; -} - -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; + return wcIdxs_[idxOH].size(); } -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; -} diff --git a/src/CoinOddWheelSeparator.hpp b/src/CoinOddWheelSeparator.hpp index 574915c9..dbc3929e 100644 --- a/src/CoinOddWheelSeparator.hpp +++ b/src/CoinOddWheelSeparator.hpp @@ -21,6 +21,7 @@ #define COINODDWHEELSEPARATOR_HPP #include "CoinUtilsConfig.h" +#include class CoinConflictGraph; class CoinShortestPath; @@ -79,7 +80,7 @@ class COINUTILSLIB_EXPORT CoinOddWheelSeparator { /** * Return the number of cuts separated. **/ - size_t numOddWheels() const { return numOH_; } + size_t numOddWheels() const { return ohIdxs_.size(); } /** * The inequality for a discovered odd hole may be @@ -117,12 +118,12 @@ class COINUTILSLIB_EXPORT CoinOddWheelSeparator { /** * Add a odd hole **/ - bool addOddHole(size_t nz, const size_t *idxs); + bool addOddHole(size_t nz, const std::vector &idxs); /** * Check if the odd hole has already been inserted. **/ - bool alreadyInserted(size_t nz, const size_t *idxs); + bool alreadyInserted(size_t nz, const std::vector &idxs); /** * Search an wheel center for the i-th discovered @@ -156,30 +157,30 @@ class COINUTILSLIB_EXPORT CoinOddWheelSeparator { * Interesting columns that will be considered * in the cut separation. **/ - size_t *icaIdx_; + std::vector icaIdx_; /** * Mapping of the fractional solution value to * an integer value to made further computations * easier. **/ - double *icaActivity_; + std::vector icaActivity_; /** * Start index for arcs of each node. * Used in the shortest path algorithm. **/ - size_t *spArcStart_; + std::vector spArcStart_; /** * Destination of each arc. * Used in the shortest path algorithm. **/ - size_t *spArcTo_; + std::vector spArcTo_; /** * Distance for each arc. * Used in the shortest path algorithm. **/ - double *spArcDist_; + std::vector spArcDist_; /** * Capacity to store arcs. **/ @@ -188,51 +189,32 @@ class COINUTILSLIB_EXPORT CoinOddWheelSeparator { /** * Auxiliary array **/ - size_t *tmp_; + std::vector tmp_; /** * Auxiliary array used in lifted module. **/ - double *costs_; + std::vector costs_; /** * Auxiliary incidence arrays **/ - char *iv_, *iv2_; + std::vector iv_, iv2_; /** * Class that contains the shortest path algorithm. **/ CoinShortestPath *spf_; - /** - * Number of discovered odd holes - **/ - size_t numOH_; - /** - * Capacity for odd hole elements - **/ - size_t capOHIdxs_; - /** - * Start indexes for the i-th odd hole - **/ - size_t *ohStart_; /** * Indexes of all odd holes **/ - size_t *ohIdxs_; - /** - * Capacity for odd hole wheel centers - **/ - size_t capWCIdx_; + std::vector > ohIdxs_; + /** * Indexes of all wheel centers **/ - size_t *wcIdxs_; - /** - * Positions where each wheel center starts - **/ - size_t *wcStart_; + std::vector > wcIdxs_; /** * Lifting strategy: 0 = no lifting, From cce8633abe01f03146c636da5949a2ebad1275ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Mon, 19 Aug 2024 17:41:54 +0200 Subject: [PATCH 05/10] CoinDynamicConflictGraph: Replace pointer arrays by std::vector --- src/CoinDynamicConflictGraph.cpp | 113 +++++++------------------------ src/CoinDynamicConflictGraph.hpp | 34 ++-------- 2 files changed, 33 insertions(+), 114 deletions(-) diff --git a/src/CoinDynamicConflictGraph.cpp b/src/CoinDynamicConflictGraph.cpp index dcc028d0..677bcef2 100644 --- a/src/CoinDynamicConflictGraph.cpp +++ b/src/CoinDynamicConflictGraph.cpp @@ -34,10 +34,6 @@ #define CG_INI_SPACE_NODE_CONFLICTS 32 -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 ); - // used to compare values bool isEqual(const double a, const double b) { if (a == b) { @@ -103,8 +99,8 @@ bool sort_columns(const std::pair< size_t, double > &left, const std::pair< size CoinDynamicConflictGraph::CoinDynamicConflictGraph ( size_t _size ) : CoinConflictGraph ( _size ) , conflicts( new CoinAdjacencyVector(_size, CG_INI_SPACE_NODE_CONFLICTS) ) - , degree_( (size_t*) xmalloc(sizeof(size_t)*_size) ) - , modifiedDegree_( (size_t*) xcalloc(_size, sizeof(size_t)) ) + , degree_(std::vector(_size)) + , modifiedDegree_(std::vector(_size)) , largeClqs( new CoinCliqueList( 4096, 32768 ) ) { } @@ -126,21 +122,17 @@ CoinDynamicConflictGraph::CoinDynamicConflictGraph ( const double* rowRange ) { iniCoinConflictGraph( numCols*2 ); - degree_ = (size_t*) xmalloc(sizeof(size_t)*(numCols*2)); - modifiedDegree_ = (size_t*) xcalloc(numCols*2, sizeof(size_t)); + degree_ = std::vector(numCols*2); + modifiedDegree_ = std::vector(numCols*2); largeClqs = new CoinCliqueList( 4096, 32768 ); - this->tElCap = matrixByRow->getNumElements() * 2; - this->tRowElements = (std::pair< size_t, double > *) xmalloc( sizeof(std::pair< size_t, double >)*tElCap); - this->tnRowCap = matrixByRow->getNumRows() * 2; - this->tRowStart = (size_t *) xmalloc(sizeof(size_t) * (tnRowCap+1) ); - this->tRowStart[0] = 0; - this->tRowRHS = (double *) xmalloc(sizeof(double) * tnRowCap ); - this->tnRows = 0; - this->tnEl = 0; + this->tRowElements = std::vector > >(); + size_t tnRowCap = matrixByRow->getNumRows() * 2; + this->tRowRHS = std::vector(); + tRowRHS.reserve(tnRowCap); // temporary area - size_t *clqIdxs = new size_t[numCols*2]; + std::vector clqIdxs(numCols*2); // maximum number of nonzeros in constraints that // will be handled pairwise @@ -151,10 +143,10 @@ CoinDynamicConflictGraph::CoinDynamicConflictGraph ( const double *coefs = matrixByRow->getElements(); const CoinBigIndex *start = matrixByRow->getVectorStarts(); const int *length = matrixByRow->getVectorLengths(); - std::pair< size_t, double > *columns = new std::pair< size_t, double >[numCols]; + std::vector > columns(numCols); smallCliques = new CoinCliqueList( 4096, 3276 ); - size_t *tmpClq = (size_t *) xmalloc( sizeof(size_t)*size_ ); + std::vector tmpClq(size_); for (size_t idxRow = 0; idxRow < (size_t)matrixByRow->getNumRows(); idxRow++) { const char rowSense = sense[idxRow]; @@ -217,16 +209,16 @@ CoinDynamicConflictGraph::CoinDynamicConflictGraph ( if (nz >= CoinConflictGraph::minClqRow_) { for ( size_t ie=0 ; ieaddClique( nz, tmpClq ); + smallCliques->addClique( nz, tmpClq.data() ); } } else { if (twoLargest[0]!=twoSmallest[0]) - std::sort(columns, columns + nz, sort_columns); + std::sort(columns.begin(), columns.begin() + nz, sort_columns); // checking variables where aj > b // and updating their bounds @@ -248,7 +240,7 @@ CoinDynamicConflictGraph::CoinDynamicConflictGraph ( maxNzOC = std::max(maxNzOC, nz); - this->addTmpRow( nz, &columns[0], rhs ); + this->addTmpRow( nz, columns, rhs ); if (rowSense == 'E' || rowSense == 'R') { if (rowSense == 'E') { @@ -269,7 +261,7 @@ CoinDynamicConflictGraph::CoinDynamicConflictGraph ( assert(rhs >= 0.0); #endif - this->addTmpRow( nz, &columns[0], rhs ); + this->addTmpRow( nz, columns, rhs ); } // equality constraints } // not explicit clique @@ -289,8 +281,8 @@ CoinDynamicConflictGraph::CoinDynamicConflictGraph ( } //detecting cliques in less-structured constraints - for ( size_t idxTR =0 ; (idxTRcomputeNodeOccurrences( size_ ); - char *iv = (char *) calloc( size_, sizeof(char) ); - if (!iv) { - fprintf( stderr, "out of memory.\n" ); - abort(); - } + std::vector iv(size_); for ( size_t k=0 ; ( knDifferentNodes() ) ; ++k ) { size_t idxNode = smallCliques->differentNodes()[k]; const size_t nNodeCliques = smallCliques->nNodeOccurrences(idxNode); const size_t *nodeCliques = smallCliques->nodeOccurrences(idxNode); - processSmallCliquesNode(idxNode, nodeCliques, nNodeCliques, smallCliques, iv); + processSmallCliquesNode(idxNode, nodeCliques, nNodeCliques, smallCliques, iv.data()); } - free( iv ); } // small cliques delete smallCliques; smallCliques = NULL; conflicts->flush(); recomputeDegree(); - - delete[] columns; - delete[] clqIdxs; - free(tRowElements); - free(tRowStart); - free(tRowRHS); - free(tmpClq); } void CoinDynamicConflictGraph::addClique( size_t size, const size_t elements[] ) { @@ -421,7 +401,7 @@ size_t clique_start(const std::pair< size_t, double > *columns, size_t nz, doubl return right + 1; } -void CoinDynamicConflictGraph::cliqueDetection(const std::pair< size_t, double > *columns, size_t nz, const double rhs) +void CoinDynamicConflictGraph::cliqueDetection(const std::vector >&columns, size_t nz, const double rhs) { #ifdef DEBUGCG assert(nz > 1); @@ -433,7 +413,7 @@ void CoinDynamicConflictGraph::cliqueDetection(const std::pair< size_t, double > size_t cliqueSize = 0; size_t *idxs = new size_t[nz]; - const size_t cliqueStart = clique_start(columns, nz, rhs); + const size_t cliqueStart = clique_start(columns.data(), nz, rhs); #ifdef DEBUGCG assert(cliqueStart >= 0); @@ -455,7 +435,7 @@ void CoinDynamicConflictGraph::cliqueDetection(const std::pair< size_t, double > break; } - size_t position = binary_search(columns, j, rhs, cliqueStart, nz - 1); + size_t position = binary_search(columns.data(), j, rhs, cliqueStart, nz - 1); #ifdef DEBUGCG assert(position >= cliqueStart && position <= nz - 1); @@ -492,8 +472,6 @@ CoinDynamicConflictGraph::~CoinDynamicConflictGraph() { delete conflicts; delete largeClqs; - free( degree_ ); - free(modifiedDegree_); if (smallCliques) delete smallCliques; } @@ -527,49 +505,10 @@ void CoinDynamicConflictGraph::printInfo() const printf("\tncliques: %zu (min: %zu, max: %zu)\n", nCliques(), minClq, maxClq ); } -void CoinDynamicConflictGraph::addTmpRow( size_t nz, const std::pair< size_t, double > *els, double rhs ) -{ - memcpy( tRowElements + tnEl, els, sizeof(std::pair< size_t, double>)*nz ); - - tnEl += nz; - - tRowRHS[tnRows] = rhs; - tnRows++; - tRowStart[tnRows] = tRowStart[tnRows-1] + nz; -} - -static void *xrealloc( void *ptr, const size_t size ) +void CoinDynamicConflictGraph::addTmpRow(size_t nz, const std::vector > &els, double rhs) { - void * res = realloc( ptr, size ); - if (!res) - { - fprintf(stderr, "No more memory available. Trying to allocate %zu bytes.", size); - abort(); - } - - return res; -} - -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 *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; + tRowRHS.push_back(rhs); + tRowElements.push_back(std::vector >(els.begin(), els.begin() + nz)); } size_t CoinDynamicConflictGraph::nDirectConflicts( size_t idxNode ) const diff --git a/src/CoinDynamicConflictGraph.hpp b/src/CoinDynamicConflictGraph.hpp index a4fef4b0..5d680316 100644 --- a/src/CoinDynamicConflictGraph.hpp +++ b/src/CoinDynamicConflictGraph.hpp @@ -194,7 +194,7 @@ class COINUTILSLIB_EXPORT CoinDynamicConflictGraph : public CoinConflictGraph /** * Try to detect cliques in a constraint **/ - void cliqueDetection( const std::pair< size_t, double > *columns, size_t nz, const double rhs ); + void cliqueDetection(const std::vector >&columns, size_t nz, const double rhs); /** * Add a clique. It will be stored explicitly or not @@ -215,7 +215,7 @@ class COINUTILSLIB_EXPORT CoinDynamicConflictGraph : public CoinConflictGraph /** * Add a row in the temporary space **/ - void addTmpRow( size_t nz, const std::pair< size_t, double > *els, double rhs); + void addTmpRow( size_t nz, const std::vector > &, double rhs); /** * Conflicts stored directly (not as cliques) @@ -225,12 +225,12 @@ class COINUTILSLIB_EXPORT CoinDynamicConflictGraph : public CoinConflictGraph /** * Degree of the nodes **/ - size_t *degree_; + std::vector degree_; /** * Modified degree of the nodes **/ - size_t *modifiedDegree_; + std::vector modifiedDegree_; /** * Conflicts stored as cliques @@ -250,33 +250,13 @@ class COINUTILSLIB_EXPORT CoinDynamicConflictGraph : public CoinConflictGraph /** * Temporary space for storing rows **/ - std::pair< size_t, double > *tRowElements; - /** - * Number of elements of the temporary space for storing rows - **/ - size_t tnEl; - /** - * Capacity of the temporary space for storing rows - **/ - size_t tElCap; - /** - * Number of rows stored in the temporary space - **/ - size_t tnRows; - /** - * Capacity for storing rows in the temporary space - **/ - size_t tnRowCap; - /** - * Indicates where each row start in the - * temporary space - **/ - size_t *tRowStart; + std::vector > > tRowElements; + /** * Stores the right-hand side of each row in the * temporary space. **/ - double *tRowRHS; + std::vector tRowRHS; }; #endif // DYNAMICCONFLICTGRAPH_H From 565af4db83aa2770287f0de553e0663c7d1324ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Tue, 20 Aug 2024 10:49:56 +0200 Subject: [PATCH 06/10] CoinStaticConflictGraph: Replace pointer arrays by std::vector --- src/CoinStaticConflictGraph.cpp | 175 +++++++------------------------- src/CoinStaticConflictGraph.hpp | 55 ++-------- 2 files changed, 45 insertions(+), 185 deletions(-) diff --git a/src/CoinStaticConflictGraph.cpp b/src/CoinStaticConflictGraph.cpp index e50603a4..ce0a3d4d 100644 --- a/src/CoinStaticConflictGraph.cpp +++ b/src/CoinStaticConflictGraph.cpp @@ -26,10 +26,6 @@ #include "CoinDynamicConflictGraph.hpp" #include "CoinCliqueList.hpp" -static void *xmalloc( const size_t size ); - -#define NEW_VECTOR(type, size) ((type *) xmalloc((sizeof(type))*(size))) - CoinStaticConflictGraph::CoinStaticConflictGraph ( const CoinConflictGraph *cgraph ) { iniCoinStaticConflictGraph(cgraph); @@ -55,9 +51,7 @@ CoinStaticConflictGraph::CoinStaticConflictGraph ( bool CoinStaticConflictGraph::nodeInClique( size_t idxClique, size_t node ) const { - const size_t *st = cliqueElements( idxClique ); - const size_t *ed = st + cliqueSize_[idxClique]; - return std::binary_search(st, ed, node); + return std::binary_search(cliques_[idxClique].begin(), cliques_[idxClique].end(), node); } CoinStaticConflictGraph *CoinStaticConflictGraph::clone() const @@ -65,50 +59,38 @@ CoinStaticConflictGraph *CoinStaticConflictGraph::clone() const return new CoinStaticConflictGraph ( this ); } -static void *xmalloc( const size_t size ) -{ - void *result = malloc( size ); - if (!result) - { - fprintf(stderr, "No more memory available. Trying to allocate %zu bytes in CoinStaticConflictGraph.\n", size); - exit(1); - } - - return result; -} - size_t CoinStaticConflictGraph::nDirectConflicts ( size_t idxNode ) const { - return this->nConflictsNode_[idxNode]; + return this->conflicts_[idxNode].size(); } const size_t * CoinStaticConflictGraph::directConflicts ( size_t idxNode ) const { - return this->conflicts_ + startConfNodes_[idxNode]; + return this->conflicts_[idxNode].data(); } size_t CoinStaticConflictGraph::nCliques() const { - return this->nCliques_; + return this->cliques_.size(); } const size_t * CoinStaticConflictGraph::cliqueElements ( size_t idxClique ) const { - return this->cliques_ + startClique_[idxClique]; + return this->cliques_[idxClique].data(); } size_t CoinStaticConflictGraph::cliqueSize( size_t idxClique ) const { - return this->cliqueSize_[idxClique]; + return this->cliques_[idxClique].size(); } const size_t * CoinStaticConflictGraph::nodeCliques ( size_t idxNode ) const { - return nodeCliques_ + startNodeCliques_[idxNode]; + return nodeCliques_[idxNode].data(); } size_t CoinStaticConflictGraph::nNodeCliques ( size_t idxNode ) const { - return this->nNodeCliques_[idxNode]; + return this->nodeCliques_[idxNode].size(); } void CoinStaticConflictGraph::setDegree(size_t idxNode, size_t deg) @@ -136,25 +118,20 @@ CoinStaticConflictGraph::CoinStaticConflictGraph( const CoinConflictGraph *cgrap iniCoinConflictGraph( n ); #define REMOVED std::numeric_limits< size_t >::max() - nDirectConflicts_ = totalCliqueElements_ = nCliques_ = memSize_ = 0; + nDirectConflicts_ = totalCliqueElements_ = 0; std::vector< size_t > newIdx( cgraph->size(), REMOVED ); for ( size_t i=0 ; (i iv(size_); std::vector< bool > ivNeighs; // large and small cliques set CoinCliqueList smallClqs( 4096, 32768 ); CoinCliqueList largeClqs( 4096, 32768 ); - size_t *clqEls = (size_t *) xmalloc( sizeof(size_t)*size_ ); + std::vector clqEls(size_); // separating new cliques (removing variables) into small and large for ( size_t ic = 0 ; (icnCliques()) ; ++ic ) { @@ -168,9 +145,9 @@ CoinStaticConflictGraph::CoinStaticConflictGraph( const CoinConflictGraph *cgrap } if ( nEl >= CoinConflictGraph::minClqRow_ ) { - largeClqs.addClique( nEl, clqEls ); + largeClqs.addClique( nEl, clqEls.data() ); } else { - smallClqs.addClique( nEl, clqEls ); + smallClqs.addClique( nEl, clqEls.data() ); } } @@ -242,11 +219,7 @@ CoinStaticConflictGraph::CoinStaticConflictGraph( const CoinConflictGraph *cgrap // computing new number of direct conflicts per node size_t prevTotalDC = 0; - size_t *prevDC = (size_t *) calloc( size_, sizeof(size_t) ); - if (!prevDC) { - fprintf( stderr, "no memory available.\n"); - abort(); - } + std::vector prevDC(size_); for ( size_t i=0 ; (i(size_); + modifiedDegree_ = std::vector(size_); + conflicts_ = std::vector >(size_); + nodeCliques_ = std::vector >(size_); + cliques_ = std::vector >(largeClqs.nCliques()); // filling cliques - startClique_[0] = 0; for ( size_t i=0 ; (i(largeClqs.cliqueElements(i), largeClqs.cliqueElements(i) + largeClqs.cliqueSize(i)); } // reusing vector - size_t *conf = clqEls; + std::vector conf = clqEls; // copying remaining direct conflicts // adding new conflicts when they exist - startConfNodes_[0] = 0; - size_t *pconf = conflicts_; for ( size_t i=0 ; (inNodeCliques_[i] = largeClqs.nNodeOccurrences(i); - - startNodeCliques_[0] = 0; - for ( size_t i=1 ; i<=size_ ; ++i ) - startNodeCliques_[i] = startNodeCliques_[i-1] + nNodeCliques_[i-1]; - // filling node cliques for ( size_t i=0 ; inodeCliques_ + startNodeCliques_[i], largeClqs.nodeOccurrences(i), sizeof(size_t)*largeClqs.nNodeOccurrences(i) ); - - free( iv ); - free( clqEls ); - free( prevDC ); + if (largeClqs.nNodeOccurrences(i)) + nodeCliques_[i] = std::vector(largeClqs.nodeOccurrences(i), largeClqs.nodeOccurrences(i) + largeClqs.nNodeOccurrences(i)); this->recomputeDegree(); #undef REMOVED @@ -355,7 +292,6 @@ size_t CoinStaticConflictGraph::nTotalCliqueElements() const { CoinStaticConflictGraph::~CoinStaticConflictGraph() { - free( nConflictsNode_ ); } const std::vector< std::pair< size_t, std::pair< double, double > > > & CoinStaticConflictGraph::updatedBounds() const @@ -367,71 +303,38 @@ void CoinStaticConflictGraph::iniCoinStaticConflictGraph(const CoinConflictGraph iniCoinConflictGraph(cgraph); nDirectConflicts_ = cgraph->nTotalDirectConflicts(); totalCliqueElements_ = cgraph->nTotalCliqueElements(); - nCliques_ = cgraph->nCliques(); - memSize_ = sizeof(size_t)*( 6*size_ + 3 + nDirectConflicts_ + 2*totalCliqueElements_ + 2*nCliques_ ); - nConflictsNode_ = (size_t *)xmalloc( memSize_ ); - degree_ = nConflictsNode_ + size_; - modifiedDegree_ = degree_ + size_; - startConfNodes_ = modifiedDegree_ + size_ ; - conflicts_ = startConfNodes_ + (size_ + 1); - nNodeCliques_ = conflicts_ + nDirectConflicts_; - startNodeCliques_ = nNodeCliques_ + size_ ; - nodeCliques_ = startNodeCliques_ + size_ + 1; - cliqueSize_ = nodeCliques_ + totalCliqueElements_; - startClique_ = cliqueSize_ + nCliques_; - cliques_ = startClique_ + nCliques_ + 1; - - std::fill( nConflictsNode_, nConflictsNode_+(3*size_), 0); // clears nConflictsNode, degree and modified degree - std::fill( nNodeCliques_, nNodeCliques_+size_, 0); // clears the number of cliques each node appears - std::fill( cliqueSize_, cliqueSize_+nCliques_, 0); - startNodeCliques_[0] = 0; - startClique_[0] = 0; + + degree_ = std::vector(size_, 0); + modifiedDegree_ = std::vector(size_, 0); + conflicts_ = std::vector >(size_); + nodeCliques_ = std::vector >(size_); + cliques_ = std::vector >(cgraph->nCliques()); // copying direct conflicts - startConfNodes_[0] = 0; - size_t *pconf = conflicts_; for ( size_t i=0 ; (inDirectConflicts(i); const size_t *conf = cgraph->directConflicts(i); - startConfNodes_[i+1] = startConfNodes_[i] + sizeConf; - nConflictsNode_[i] = sizeConf; - - memcpy( pconf, conf, sizeof(size_t)*sizeConf ); - pconf += sizeConf; + conflicts_[i] = std::vector(conf, conf + sizeConf); } // all nodes // copying cliques - startClique_[0] = 0; for ( size_t ic=0 ; ( ic<(size_t)cgraph->nCliques() ) ; ++ic ) { const size_t *clique = cgraph->cliqueElements(ic); - cliqueSize_[ic] = cgraph->cliqueSize(ic); - const size_t *cliqueEnd = clique + cliqueSize_[ic]; - startClique_[ic+1] = startClique_[ic] + cliqueSize_[ic]; - size_t pc = startClique_[ic]; + const size_t *cliqueEnd = clique + cgraph->cliqueSize(ic); // copying clique contents - memcpy( &cliques_[pc], clique, sizeof(size_t)*cliqueSize_[ic] ); - for ( const size_t *cl = clique ; cl(clique, cliqueEnd); } // filling node cliques - startNodeCliques_[0] = 0; - for ( size_t in=1 ; (in<=size()) ; ++in ) - startNodeCliques_[in] = startNodeCliques_[in-1] + nNodeCliques_[in-1]; - - size_t *posNodeCliques = (size_t *) NEW_VECTOR(size_t, size_); - memcpy(posNodeCliques, startNodeCliques_, sizeof(size_t)*size_ ); - - // filling node cliques - for ( size_t ic=0 ; ( ic < nCliques_ ) ; ++ic ) + for ( size_t ic=0 ; ( ic < cgraph->nCliques() ) ; ++ic ) { const size_t *clq = cliqueElements(ic); - const size_t clqSize = cliqueSize_[ic]; + const size_t clqSize = cliques_[ic].size(); for ( size_t iclqe=0 ; (iclqesetDegree(i, cgraph->degree(i)); this->setModifiedDegree(i, cgraph->modifiedDegree(i)); } - - free(posNodeCliques); } diff --git a/src/CoinStaticConflictGraph.hpp b/src/CoinStaticConflictGraph.hpp index 039efa85..9efb3428 100644 --- a/src/CoinStaticConflictGraph.hpp +++ b/src/CoinStaticConflictGraph.hpp @@ -23,6 +23,8 @@ #include "CoinConflictGraph.hpp" #include "CoinDynamicConflictGraph.hpp" +#include + /** * Static conflict graph, optimized for memory usage and query speed, * not modifiable. @@ -187,74 +189,31 @@ class COINUTILSLIB_EXPORT CoinStaticConflictGraph : public CoinConflictGraph **/ size_t totalCliqueElements_; - /** - * Number of cliques stored explicitly. - **/ - size_t nCliques_; - - /** - * Required memory for all vectors. - **/ - size_t memSize_; - - /** - * Number of direct conflicts per node. - **/ - size_t *nConflictsNode_; - /** * Degree of each node. **/ - size_t *degree_; + std::vector degree_; /** * Modified degree of each node. **/ - size_t *modifiedDegree_; - - /** - * Start position for the direct conflicts - * of each node. - **/ - size_t *startConfNodes_; + std::vector modifiedDegree_; /** * Direct conflicts **/ - size_t *conflicts_; - - /** - * Number of cliques that a node appears. - **/ - size_t *nNodeCliques_; - - /** - * Indicates the first position of nodeCliques_ - * that has the indexes of cliques containing - * a node. - **/ - size_t *startNodeCliques_; + std::vector > conflicts_; /** * Array containing, for each node, * the cliques that contain this node. **/ - size_t *nodeCliques_; - - /** - * Size of the cliques stored explicitly. - **/ - size_t *cliqueSize_; - - /** - * First position where each clique starts. - **/ - size_t *startClique_; + std::vector > nodeCliques_; /** * Elements of the cliques stored explicitly. **/ - size_t *cliques_; + std::vector > cliques_; }; #endif // STATICCONFLICTGRAPH_H From 1ea1ab7c017a0879474bfbdc2b3b96025208d828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Tue, 20 Aug 2024 16:00:37 +0200 Subject: [PATCH 07/10] CoinCliqueList: Replace pointer arrays by std::vector --- src/CoinCliqueList.cpp | 122 ++++++++++------------------------------- src/CoinCliqueList.hpp | 34 ++---------- 2 files changed, 33 insertions(+), 123 deletions(-) diff --git a/src/CoinCliqueList.cpp b/src/CoinCliqueList.cpp index b39e366b..da2348e7 100644 --- a/src/CoinCliqueList.cpp +++ b/src/CoinCliqueList.cpp @@ -27,104 +27,51 @@ #include "CoinConflictGraph.hpp" #endif -static void *xrealloc( void *ptr, const size_t size ); -static void *xmalloc( const size_t size ); - CoinCliqueList::CoinCliqueList( size_t _iniClqCap, size_t _iniClqElCap ) - : nCliques_( 0 ) - , cliquesCap_( _iniClqCap ) + : cliquesCap_( _iniClqCap ) , nCliqueElements_( 0 ) - , nCliqueElCap_( _iniClqElCap ) - , clqStart_( (size_t *) xmalloc( sizeof(size_t)*(cliquesCap_+1) ) ) - , clqSize_( (size_t *) xmalloc( sizeof(size_t)*(cliquesCap_) ) ) - , clqEls_( (size_t *) xmalloc( sizeof(size_t)*(nCliqueElCap_) ) ) - , nodeOccur_( NULL ) - , startNodeOccur_( NULL ) , nDifferent_ ( 0 ) - , diffNodes_( NULL ) { - clqStart_[0] = 0; } void CoinCliqueList::addClique(size_t size, const size_t els[]) { - if (nCliques_+1 > cliquesCap_) { + if (clqEls_.size()+1 > cliquesCap_) { cliquesCap_ *= 2; - clqStart_ = (size_t *) xrealloc( clqStart_, sizeof(size_t)*(cliquesCap_+1) ); - clqSize_= (size_t *) xrealloc( clqSize_, sizeof(size_t)*(cliquesCap_) ); + this->clqEls_.reserve(cliquesCap_); } - clqStart_[nCliques_+1] = clqStart_[nCliques_] + size; - clqSize_[nCliques_] = size; - if ( nCliqueElements_ + size > nCliqueElCap_ ) { - nCliqueElCap_ = std::max(nCliqueElements_ + size, nCliqueElCap_*2); - this->clqEls_ = (size_t *) xrealloc( this->clqEls_, sizeof(size_t)*nCliqueElCap_ ); - } - memcpy( clqEls_ + nCliqueElements_, els, sizeof(size_t)*size ); + clqEls_.push_back(std::vector(els, els + size)); - nCliques_++; nCliqueElements_ += size; } size_t CoinCliqueList::cliqueSize( size_t idxClq ) const { - return this->clqSize_[idxClq]; + return this->clqEls_[idxClq].size(); } const size_t *CoinCliqueList::cliqueElements( size_t idxClq ) const { - return this->clqEls_ + this->clqStart_[idxClq]; + return this->clqEls_[idxClq].data(); } CoinCliqueList::~CoinCliqueList() { - free( clqStart_ ); - free( clqSize_ ); - free( clqEls_ ); - - if (nodeOccur_) { - free(nodeOccur_); - free(startNodeOccur_); - free(diffNodes_); - } -} - -static void *xmalloc( const size_t size ) -{ - void *result = malloc( size ); - if (!result) - { - fprintf(stderr, "No more memory available. Trying to allocate %zu bytes in CoinCliqueList.\n", size); - exit(1); - } - - return result; } void CoinCliqueList::computeNodeOccurrences(size_t nNodes) { - if (nodeOccur_) { - free(nodeOccur_); - free(startNodeOccur_); - free(diffNodes_); - nodeOccur_ = startNodeOccur_ = diffNodes_ = NULL; - } - - startNodeOccur_ = (size_t *)xmalloc( sizeof(size_t)*(nNodes+1) ); - nodeOccur_ = (size_t *)xmalloc( sizeof(size_t)*nCliqueElements_ ); + nodeOccur_ = std::vector >(nNodes); // couting number of occurrences for each node - size_t *noc = (size_t *)calloc( nNodes, sizeof(size_t) ); - if (!noc) { - fprintf( stderr, "No more memory available.\n" ); - abort(); + std::vector noc(nNodes, 0); + for (size_t i=0; i < clqEls_.size(); ++i) { + for (size_t j=0; j < clqEls_[i].size(); ++j) + noc[clqEls_[i][j]]++; } - for ( size_t i=0 ; (i(noc[in]); - startNodeOccur_[0] = 0; - for ( size_t in=1 ; (in<(nNodes+1)) ; ++in ) - startNodeOccur_[in] = startNodeOccur_[in-1] + noc[in-1]; - - memset( noc, 0, sizeof(size_t)*nNodes ); + std::fill(noc.begin(), noc.end(), 0); nDifferent_ = 0; for ( size_t ic=0 ; ic(nDifferent_); nDifferent_ = 0; - for ( size_t i=0 ; (idiffNodes_; + return this->diffNodes_.data(); } size_t CoinCliqueList::nDifferentNodes() const @@ -179,7 +115,7 @@ size_t CoinCliqueList::nDifferentNodes() const const size_t * CoinCliqueList::nodeOccurrences(size_t idxNode) const { - return this->nodeOccur_ + this->startNodeOccur_[idxNode]; + return this->nodeOccur_[idxNode].data(); } size_t CoinCliqueList::totalElements() const { @@ -188,7 +124,7 @@ size_t CoinCliqueList::totalElements() const { size_t CoinCliqueList::nNodeOccurrences(size_t idxNode) const { - return this->startNodeOccur_[idxNode+1] - this->startNodeOccur_[idxNode]; + return this->nodeOccur_[idxNode].size(); } #ifdef DEBUGCG @@ -212,4 +148,4 @@ void CoinCliqueList::validateClique(const CoinConflictGraph *cgraph, const size_ } } } -#endif \ No newline at end of file +#endif diff --git a/src/CoinCliqueList.hpp b/src/CoinCliqueList.hpp index 8c9817c4..16fdbc43 100644 --- a/src/CoinCliqueList.hpp +++ b/src/CoinCliqueList.hpp @@ -21,6 +21,7 @@ #include "CoinUtilsConfig.h" #include +#include #ifdef DEBUGCG class CoinConflictGraph; @@ -123,11 +124,6 @@ class COINUTILSLIB_EXPORT CoinCliqueList #endif private: - /** - * Number of cliques stored in the list. - **/ - size_t nCliques_; - /** * Capacity to store cliques in the list. **/ @@ -138,38 +134,16 @@ class COINUTILSLIB_EXPORT CoinCliqueList **/ size_t nCliqueElements_; - /** - * Capacity to store the elements of the cliques - **/ - size_t nCliqueElCap_; - - /** - * Pointer to indicate where each clique start - **/ - size_t *clqStart_; - - /** - * Size of each clique - **/ - size_t *clqSize_; - /** * Pointer with the elements of the cliques **/ - size_t *clqEls_; + std::vector > clqEls_; /** * Store in which clique each node appears. * Only filled if computeNodeOccurrences is called. **/ - size_t *nodeOccur_; - - /** - * Pointer to indicate where each array of node - * occurrence starts. Only filled if - * computeNodeOccurrences is called. - **/ - size_t *startNodeOccur_; + std::vector > nodeOccur_; /** * Number of different nodes that are stored @@ -181,7 +155,7 @@ class COINUTILSLIB_EXPORT CoinCliqueList * Nodes (without duplicates) that are stored * in the clique list. **/ - size_t *diffNodes_; + std::vector diffNodes_; }; #endif // COINCLIQUELIST_H From 2a4d8b3523847547c6f89089c9a9ed6e3e11f95a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Tue, 20 Aug 2024 17:16:17 +0200 Subject: [PATCH 08/10] CoinCliqueSet: Replace pointer arrays by std::vector --- src/CoinCliqueSet.cpp | 106 ++++++++---------------------------------- src/CoinCliqueSet.hpp | 32 ++----------- 2 files changed, 22 insertions(+), 116 deletions(-) diff --git a/src/CoinCliqueSet.cpp b/src/CoinCliqueSet.cpp index eabcaf60..a2aebe09 100644 --- a/src/CoinCliqueSet.cpp +++ b/src/CoinCliqueSet.cpp @@ -27,108 +27,57 @@ const size_t CoinCliqueSet::sequence_[] = {37, 31, 29, 17, 13, 11, 7, 1}; const size_t CoinCliqueSet::nSequence_ = 8; const size_t CoinCliqueSet::nBuckets_ = 8192; -static void *xmalloc( const size_t size ); -static void *xrealloc( void *ptr, const size_t size ); - #define INI_SPACE_BUCKETS 32 -#define NEW_VECTOR(type, size) ((type *) xmalloc((sizeof(type))*(size))) CoinCliqueSet::CoinCliqueSet(size_t _iniClqCap, size_t _iniClqElCap) : CoinCliqueList(_iniClqCap, _iniClqElCap) - , hash_(NEW_VECTOR(size_t*, nBuckets_ * 2)) - , iniHashSpace_(NEW_VECTOR(size_t, (nBuckets_ * INI_SPACE_BUCKETS) + (2 * nBuckets_))) - , expandedBucket_(hash_ + nBuckets_) - , bucketSize_(iniHashSpace_ + (nBuckets_ * INI_SPACE_BUCKETS)) - , bucketCap_(bucketSize_ + nBuckets_) { - hash_[0] = iniHashSpace_; + , hash_(std::vector >(nBuckets_)) { for (size_t i = 1; i < nBuckets_; i++) { - hash_[i] = hash_[i-1] + INI_SPACE_BUCKETS; + hash_[i].reserve(INI_SPACE_BUCKETS); } - - std::fill(bucketSize_, bucketSize_ + nBuckets_, 0); - std::fill(bucketCap_, bucketCap_ + nBuckets_, INI_SPACE_BUCKETS); - std::fill(expandedBucket_, expandedBucket_ + nBuckets_, (size_t*)NULL); - - tmpClqCap_ = 256; - tmpClq_ = (size_t*)xmalloc(sizeof(size_t) * tmpClqCap_); } -CoinCliqueSet::~CoinCliqueSet() { - for (size_t i = 0; i < nBuckets_; i++) { - if (expandedBucket_[i]) { - free(expandedBucket_[i]); - } - } - - free(hash_); - free(iniHashSpace_); - free(tmpClq_); -} +CoinCliqueSet::~CoinCliqueSet() {} bool CoinCliqueSet::insertIfNotDuplicate(size_t size, const size_t *els) { - if (size > tmpClqCap_) { - tmpClqCap_ = std::max(size, tmpClqCap_*2); - tmpClq_ = (size_t*)xrealloc(tmpClq_, sizeof(size_t) * tmpClqCap_); - } - - memcpy(tmpClq_, els, sizeof(size_t) * size); - std::sort(tmpClq_, tmpClq_ + size); + std::vector tmpClq = std::vector(els, els + size); + std::sort(tmpClq.begin(), tmpClq.end()); - size_t idxBucket = vectorHashCode(size, tmpClq_); + size_t idxBucket = vectorHashCode(tmpClq); #ifdef DEBUGCG assert(idxBucket >= 0); assert(idxBucket < nBuckets_); #endif - if (alreadyInserted(size, tmpClq_, idxBucket)) { + if (alreadyInserted(tmpClq, idxBucket)) { return false; } - const size_t currCap = bucketCap_[idxBucket]; - const size_t currSize = bucketSize_[idxBucket]; + const size_t currCap = hash_[idxBucket].capacity(); + const size_t currSize = hash_[idxBucket].size(); /*updating capacity*/ if (currSize + 1 > currCap) { - const size_t newCap = bucketCap_[idxBucket] * 2; - - if (expandedBucket_[idxBucket]) { // already outside initial space - bucketCap_[idxBucket] = newCap; - hash_[idxBucket] = expandedBucket_[idxBucket] = (size_t *)xrealloc(expandedBucket_[idxBucket], sizeof(size_t) * newCap); - } else { - size_t iBucket = idxBucket; - while (iBucket >= 1) { - --iBucket; - if (!expandedBucket_[iBucket]) { - break; - } - } - - if (iBucket != idxBucket && !expandedBucket_[iBucket]) { - bucketCap_[iBucket] += bucketCap_[idxBucket]; - } - - bucketCap_[idxBucket] = newCap; - expandedBucket_[idxBucket] = (size_t*)xmalloc(sizeof(size_t) * newCap); - memcpy(expandedBucket_[idxBucket], hash_[idxBucket], sizeof(size_t) * currSize); - hash_[idxBucket] = expandedBucket_[idxBucket]; - } + const size_t newCap = currCap * 2; + hash_[idxBucket].reserve(newCap); } /*updating hash*/ - hash_[idxBucket][bucketSize_[idxBucket]++] = nCliques(); + hash_[idxBucket].push_back(nCliques()); /* inserting into CliqueList */ - addClique(size, tmpClq_); + addClique(size, tmpClq.data()); return true; } -size_t CoinCliqueSet::vectorHashCode(size_t size, const size_t els[]) { +size_t CoinCliqueSet::vectorHashCode(const std::vector &els) { #ifdef DEBUGCG assert(size > 0); #endif + size_t size = els.size(); size_t code = (size * sequence_[0]); code += (els[0] * sequence_[1]); @@ -146,13 +95,15 @@ size_t CoinCliqueSet::vectorHashCode(size_t size, const size_t els[]) { return code; } -bool CoinCliqueSet::alreadyInserted(size_t size, const size_t els[], size_t hashCode) { +bool CoinCliqueSet::alreadyInserted(const std::vector &els, size_t hashCode) { #ifdef DEBUGCG assert(hashCode >= 0); assert(hashCode < nBuckets_); #endif - for(size_t i = 0; i < bucketSize_[hashCode]; i++) { + size_t size = els.size(); + + for(size_t i = 0; i < hash_[hashCode].size(); i++) { const size_t idxClq = hash_[hashCode][i]; #ifdef DEBUGCG @@ -181,22 +132,3 @@ bool CoinCliqueSet::alreadyInserted(size_t size, const size_t els[], size_t hash return false; } -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 * result = realloc( ptr, size ); - if (!result) { - fprintf(stderr, "No more memory available. Trying to allocate %zu bytes in CoinCliqueList", size); - abort(); - } - - return result; -} \ No newline at end of file diff --git a/src/CoinCliqueSet.hpp b/src/CoinCliqueSet.hpp index 71721561..1d6187f3 100644 --- a/src/CoinCliqueSet.hpp +++ b/src/CoinCliqueSet.hpp @@ -55,7 +55,7 @@ class COINUTILSLIB_EXPORT CoinCliqueSet : public CoinCliqueList { * @param size size of the clique * @param els indexes of the clique **/ - static size_t vectorHashCode(size_t size, const size_t els[]); + static size_t vectorHashCode(const std::vector &els); /** * Return whether a clique has already been @@ -66,7 +66,7 @@ class COINUTILSLIB_EXPORT CoinCliqueSet : public CoinCliqueList { * @param hashCode hash value of * the clique (call method vectorHashCode) **/ - bool alreadyInserted(size_t size, const size_t els[], size_t hashCode); + bool alreadyInserted(const std::vector &els, size_t hashCode); /** * hash multipliers @@ -86,33 +86,7 @@ class COINUTILSLIB_EXPORT CoinCliqueSet : public CoinCliqueList { /** * Pointer to the current elements for each bucket **/ - size_t **hash_; - - /** - * Initial memory allocated to the buckets - **/ - size_t *iniHashSpace_; - - /** - * Pointers to additional memory allocated - * to elements that don't fit in the initial space - **/ - size_t **expandedBucket_; - - /** - * Current size of each bucket - **/ - size_t *bucketSize_; - - /** - * Current capacity of each bucket - **/ - size_t *bucketCap_; - - /** - * Array for temporary storage of a clique - **/ - size_t *tmpClq_, tmpClqCap_; + std::vector > hash_; }; From f43973f22517992d33d584377d0dfba87970744f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Wed, 21 Aug 2024 17:39:16 +0200 Subject: [PATCH 09/10] CoinAdjacencyVector: Replace pointer arrays by std::vector --- src/CoinAdjacencyVector.cpp | 214 +++++++----------------------------- src/CoinAdjacencyVector.hpp | 36 +----- 2 files changed, 43 insertions(+), 207 deletions(-) diff --git a/src/CoinAdjacencyVector.cpp b/src/CoinAdjacencyVector.cpp index b32c9c88..f572c1c2 100644 --- a/src/CoinAdjacencyVector.cpp +++ b/src/CoinAdjacencyVector.cpp @@ -22,62 +22,36 @@ #include #include #include -#include -#include "CoinAdjacencyVector.hpp" -static void *xmalloc( const size_t size ); -static void *xrealloc( void *ptr, const size_t size ); +#include "CoinAdjacencyVector.hpp" #define KEEP_SORTED -#define NEW_VECTOR(type, size) ((type *) xmalloc((sizeof(type))*(size))) - CoinAdjacencyVector::CoinAdjacencyVector( size_t _nRows, size_t _iniRowSize ) - : nRows_( _nRows ) - , rows_( NEW_VECTOR( size_t *, (nRows_*2) ) ) - , expandedRows_( rows_ + nRows_ ) - , iniRowSpace_( NEW_VECTOR( size_t, ((nRows_ * _iniRowSize) + (3 * nRows_)) ) ) - , rowSize_( iniRowSpace_ + (nRows_ * _iniRowSize) ) - , rowCap_( rowSize_+nRows_ ) - , notUpdated_( rowCap_+nRows_ ) + : rows_(std::vector >(_nRows)) + , notUpdated_(std::vector(_nRows, 0)) { - rows_[0] = iniRowSpace_; - for ( size_t i=1 ; (inRows_); + assert(idxRowrows_.size()); - return rows_[idxRow]; + return rows_[idxRow].data(); } bool CoinAdjacencyVector::isNeighbor(size_t idxNode, size_t idxNeigh) const { - size_t *r = rows_[idxNode]; - size_t *endR = rows_[idxNode] + rowSize_[idxNode]; - #ifdef KEEP_SORTED - return std::binary_search(r, endR, idxNeigh); + return std::binary_search(rows_[idxNode].begin(), rows_[idxNode].end(), idxNeigh); #else - for ( ; (r::const_iterator i=rows_[idxNode].begin(); i != rows_[idxNode].end(); ++i) + if (*i == idxNeigh) return true; #endif @@ -87,15 +61,13 @@ bool CoinAdjacencyVector::isNeighbor(size_t idxNode, size_t idxNeigh) const { void CoinAdjacencyVector::addNeighbor( size_t idxNode, size_t idxNeigh, bool addReverse ) { checkCapNode(idxNode); #ifdef KEEP_SORTED - char res = CoinAdjacencyVector::tryAddElementSortedVector( this->rows_[idxNode], this->rowSize_[idxNode], idxNeigh ); + bool res = tryAddElementSortedVector(rows_[idxNode], idxNeigh); if (res) { - rowSize_[idxNode]++; if (addReverse) addNeighbor( idxNeigh, idxNode, false ); } #else - rows_[idxNode][rowSize_[idxNode]] = idxNeigh; - rowSize_[idxNode]++; + rows_[idxNode].push_back(idxNeigh); if (addReverse) this->addNeighbor(idxNeigh, idxNode, false); #endif @@ -104,179 +76,69 @@ void CoinAdjacencyVector::addNeighbor( size_t idxNode, size_t idxNeigh, bool add size_t CoinAdjacencyVector::rowSize( size_t idxRow ) const { - assert(idxRownRows_); - - return rowSize_[idxRow]; -} - -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(); - } + assert(idxRowrows_.size()); - return result; + return rows_[idxRow].size(); } -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.", size); - abort(); - } - - return res; -} - - void CoinAdjacencyVector::checkCapNode( const size_t idxNode, const size_t newEl ) { - assert( idxNode < nRows_ ); - - size_t currCap = rowCap_[idxNode]; - size_t currSize = rowSize_[idxNode]; + assert( idxNode < rows_.size() ); + + size_t currCap = rows_[idxNode].capacity(); + size_t currSize = rows_[idxNode].size(); // no need to resize if ( currSize + newEl <= currCap ) return; // for resizing - const size_t newIdxNodeCap = std::max( rowCap_[idxNode]*2, currSize+newEl ); - - if ( expandedRows_[idxNode] ) { - // already outside initial vector - rowCap_[idxNode] = newIdxNodeCap; - rows_[idxNode] = expandedRows_[idxNode] = (size_t *)xrealloc(expandedRows_[idxNode], sizeof(size_t)*rowCap_[idxNode] ); - return; - } -/* - // node still in the otiginal vector - { - // check extension down, if the capacity - // of the node in the border of the current - // node tight to the border of idxNode (iNode) is available and capacity is enough to - // accomodate required increase in the capacity of idxNode - - size_t iNode = idxNode; - size_t accCap = 0; - - while (accCap < rowCap_[idxNode]) { - accCap += rowCap_[iNode]; - ++iNode; - if ( iNode == nRows_ ) - break; - } - - assert( accCap == rowCap_[idxNode] ); - - if ( iNode < nRows_ && expandedRows_[iNode]==NULL && currCap + rowCap_[iNode] >= currSize + newEl ) { - expandedRows_[iNode] = (size_t *) xmalloc( sizeof(size_t)*rowCap_[iNode] ); - memcpy( expandedRows_[iNode], rows_[iNode], sizeof(size_t)*rowSize_[iNode] ); - rows_[iNode] = expandedRows_[iNode]; - rowCap_[idxNode] += rowCap_[iNode]; - return; - } - } - */ - - // will be moved outside the vector, checking if space can be used - // by some node before - { - size_t iNode = idxNode; - while (iNode >= 1) { - --iNode; - if (expandedRows_[iNode] == NULL) - break; - } - - if ( iNode != idxNode && (expandedRows_[iNode] == NULL) ) - rowCap_[iNode] += rowCap_[idxNode]; - - // allocating outside and moving - rowCap_[idxNode] = newIdxNodeCap; - expandedRows_[idxNode] = (size_t *) xmalloc( sizeof(size_t)*rowCap_[idxNode] ); - memcpy(expandedRows_[idxNode], rows_[idxNode], sizeof(size_t)*currSize ); - rows_[idxNode] = expandedRows_[idxNode]; - } + const size_t newIdxNodeCap = std::max(currCap*2, currSize+newEl); + rows_[idxNode].reserve(newIdxNodeCap); } void CoinAdjacencyVector::fastAddNeighbor( size_t idxNode, size_t idxNeigh ) { - //printf("adding to %zu %zu currCap: %zu currSize: %zu at %p\n", idxNode, idxNeigh, rowCap_[idxNode], rowSize_[idxNode], expandedRows_[idxNode] ); fflush(stdout); + //printf("adding to %zu %zu currCap: %zu currSize: %zu\n", idxNode, idxNeigh, rows_[idxNode].capacity(), rows_[idxNode].size()); fflush(stdout); checkCapNode(idxNode); - rows_[idxNode][rowSize_[idxNode]++] = idxNeigh; + rows_[idxNode].push_back(idxNeigh); notUpdated_[idxNode]++; } void CoinAdjacencyVector::sort() { - for ( size_t i=0 ; (i &el, size_t newEl) { - /* doing a binary search */ - int l = 0; - int r = n - 1; - int m; - int ip = std::numeric_limits::max(); /* insertion pos */ - - while (l <= r) { - m = (l + r) / 2; - - if (el[m] == newEl) { - return 0; - } else { - if (newEl < el[m]) { - if (m > 0) { - r = m - 1; - } else { - break; - } - } else { - l = m + 1; - } - } - } - - if (ip == std::numeric_limits::max()) { - ip = l; - } - - assert(ip <= (int)n); - - if (ip < (int)n) - memmove( el + ip + 1, el + ip, sizeof(size_t)*(n-ip) ); - - el[ip] = newEl; + std::vector::iterator pos = std::lower_bound(el.begin(), el.end(), newEl); + if (*pos == newEl) + return false; - return 1; + el.insert(pos, newEl); + return true; } size_t CoinAdjacencyVector::totalElements() const { size_t res = 0; - for ( size_t i=0 ; (inRows_) ; ++i ) { + for ( size_t i=0 ; irows_.size() ; ++i ) { if (notUpdated_[i]) { - std::sort(rows_[i], rows_[i]+rowSize_[i]); - const size_t *newEnd = std::unique(rows_[i], rows_[i]+rowSize_[i]); - rowSize_[i] = newEnd - rows_[i]; + std::sort(rows_[i].begin(), rows_[i].end()); + std::vector::iterator newEnd = std::unique(rows_[i].begin(), rows_[i].end()); + rows_[i].erase(newEnd, rows_[i].end()); notUpdated_[i] = 0; } } @@ -286,13 +148,13 @@ void CoinAdjacencyVector::addNeighborsBuffer( size_t idxNode, size_t n, const si checkCapNode(idxNode, n); for ( size_t i=0 ; (irows_[idxRow], this->rows_[idxRow] + this->rowSize(idxRow) ); + std::sort(rows_[idxRow].begin(), rows_[idxRow].end()); } /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2 diff --git a/src/CoinAdjacencyVector.hpp b/src/CoinAdjacencyVector.hpp index 35d3cc59..c489f8f7 100644 --- a/src/CoinAdjacencyVector.hpp +++ b/src/CoinAdjacencyVector.hpp @@ -20,6 +20,7 @@ #define COINADJACENCYVECTOR_H #include +#include #include "CoinUtilsConfig.h" /** @@ -107,13 +108,12 @@ class COINUTILSLIB_EXPORT CoinAdjacencyVector /** * Try to add an element to a sorted vector, keeping it sorted. - * Return 1 if element was added and 0 if it was already there. + * Return `true` if element was added and `false` if it was already there. * * @param el sorted vector - * @param n size of the sorted vector * @param newEl element to be added to the sorted vector **/ - static char tryAddElementSortedVector( size_t *el, size_t n, size_t newEl ); + static bool tryAddElementSortedVector(std::vector &el, size_t newEl); /** * Return the total number of elements. @@ -121,41 +121,15 @@ class COINUTILSLIB_EXPORT CoinAdjacencyVector size_t totalElements() const; private: - /** - * Number of nodes - **/ - size_t nRows_; - /** * Pointers to the current neighbor vector of each node **/ - size_t **rows_; - - /** - * Pointers to additional memory allocated - * to neigbors that don't fit in the initial space. - **/ - size_t **expandedRows_; - - /** - * Initial memory allocated to lines of rows_ - **/ - size_t *iniRowSpace_; - - /** - * Size of each neighbor vector - **/ - size_t *rowSize_; - - /** - * Current capacity of each neighbor vector - **/ - size_t *rowCap_; + std::vector > rows_; /** * Elements added that need to be sorted later **/ - size_t *notUpdated_; + std::vector notUpdated_; /** * Check if a node can receive a new neighbor From 8addcac0c29331ddb7ac36fcdfdcf1e481a2315a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Apitzsch?= Date: Wed, 21 Aug 2024 18:08:00 +0200 Subject: [PATCH 10/10] CoinShortestPath: Replace pointer arrays by std::vector --- src/CoinShortestPath.cpp | 49 +++++++++++++--------------------------- src/CoinShortestPath.hpp | 24 ++++++-------------- 2 files changed, 23 insertions(+), 50 deletions(-) diff --git a/src/CoinShortestPath.cpp b/src/CoinShortestPath.cpp index 66ac71be..c3349398 100644 --- a/src/CoinShortestPath.cpp +++ b/src/CoinShortestPath.cpp @@ -28,37 +28,29 @@ #define SPATH_INFTY_NODE std::numeric_limits::max() #define SPATH_INFTY_DIST std::numeric_limits::max() -static void *xmalloc( const size_t size ); - CoinShortestPath::CoinShortestPath(size_t nodes, size_t arcs, const size_t *arcStart, const size_t *toNode, const double *dist) { nodes_ = nodes; - arcs_ = arcs; nh_ = new CoinNodeHeap(nodes_); - previous_ = (size_t*)xmalloc(sizeof(size_t) * nodes_); - dist_ = (double*)xmalloc(sizeof(double) * nodes_); - path_ = (size_t*)xmalloc(sizeof(size_t) * nodes_); - neighs_ = (std::pair*)xmalloc(sizeof(std::pair) * arcs_); - startn_ = (std::pair**)xmalloc(sizeof(std::pair*) * (nodes_ + 1)); - - for (size_t idx = 0; idx < arcs_; idx++) { - neighs_[idx].first = toNode[idx]; - neighs_[idx].second = dist[idx]; + previous_ = std::vector(nodes_); + dist_ = std::vector(nodes_); + path_ = std::vector(nodes_); + neighs_ = std::vector > >(nodes_); + + size_t idx = 0; + for (size_t n = 0; n < nodes_; n++) { + neighs_[n] = std::vector >(arcStart[n+1] - arcStart[n]); + for (size_t i = 0; i < neighs_[n].size(); ++i) { + neighs_[n][i].first = toNode[idx]; + neighs_[n][i].second = dist[idx]; #ifdef DEBUGCG - assert(neighs_[idx].first < nodes); + assert(neighs_[n][i].first < nodes); #endif - } - - for (size_t n = 0; n <= nodes_; n++) { - startn_[n] = neighs_ + arcStart[n]; + idx++; + } } } CoinShortestPath::~CoinShortestPath() { - free(neighs_); - free(startn_); - free(previous_); - free(dist_); - free(path_); delete nh_; } @@ -83,7 +75,7 @@ void CoinShortestPath::find(const size_t origin) { assert(topCost + SPATH_EPS <= SPATH_INFTY_DIST); #endif // updating neighbors distances by iterating in all neighbors - for (std::pair *n = startn_[topNode]; n < startn_[topNode+1]; n++) { + for (std::vector >::iterator n = neighs_[topNode].begin(); n != neighs_[topNode].end(); ++n) { const size_t toNode = n->first; const double dist = n->second; const double newDist = topCost + dist; @@ -124,7 +116,7 @@ void CoinShortestPath::find(const size_t origin, const size_t destination) { break; } // updating neighbors distances by iterating in all neighbors - for (std::pair *n = startn_[topNode]; n < startn_[topNode+1]; n++) { + for (std::vector >::iterator n = neighs_[topNode].begin(); n != neighs_[topNode].end(); ++n) { const size_t toNode = n->first; const double dist = n->second; const double newDist = topCost + dist; @@ -170,12 +162,3 @@ size_t CoinShortestPath::previous(size_t node) const { return previous_[node]; } -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; -} diff --git a/src/CoinShortestPath.hpp b/src/CoinShortestPath.hpp index 7d361e35..8971110f 100644 --- a/src/CoinShortestPath.hpp +++ b/src/CoinShortestPath.hpp @@ -23,6 +23,7 @@ #include "CoinUtilsConfig.h" #include #include +#include class CoinNodeHeap; @@ -79,7 +80,7 @@ class COINUTILSLIB_EXPORT CoinShortestPath { /** * Return the number of arcs in the graph. **/ - size_t numArcs() const { return arcs_; } + size_t numArcs() const { return neighs_.size(); } /** * Return the length of the shortest path @@ -99,7 +100,7 @@ class COINUTILSLIB_EXPORT CoinShortestPath { * nodes which should be steped to arrive * at a given node. **/ - const size_t* previous() const { return previous_; } + const size_t* previous() const { return previous_.data(); } private: /** @@ -107,37 +108,26 @@ class COINUTILSLIB_EXPORT CoinShortestPath { **/ size_t nodes_; - /** - * Number of arcs in the graph. - **/ - size_t arcs_; - /** * Array containing all neighbors **/ - std::pair *neighs_; - - /** - * Start of neighbors for node i. The - * neighbor ends at startn[i+1]. - **/ - std::pair **startn_; + std::vector > > neighs_; /** * Length of the shortest paths. **/ - double *dist_; + std::vector dist_; /** * Array indexes with all previous nodes which * should be steped to arrive at a given node. **/ - size_t *previous_; + std::vector previous_; /** * Temporary storage for the shortest paths. **/ - size_t *path_; + std::vector path_; /** * Monotone heap used in Dijkstra's algorithm.