/** resizes cuts and score arrays to be able to store at least num entries */ static SCIP_RETCODE sepastoreEnsureCutsMem( SCIP_SEPASTORE* sepastore, /**< separation storage */ SCIP_SET* set, /**< global SCIP settings */ int num /**< minimal number of slots in array */ ) { assert(sepastore != NULL); assert(set != NULL); if( num > sepastore->cutssize ) { int newsize; newsize = SCIPsetCalcMemGrowSize(set, num); SCIP_ALLOC( BMSreallocMemoryArray(&sepastore->cuts, newsize) ); SCIP_ALLOC( BMSreallocMemoryArray(&sepastore->efficacies, newsize) ); SCIP_ALLOC( BMSreallocMemoryArray(&sepastore->objparallelisms, newsize) ); SCIP_ALLOC( BMSreallocMemoryArray(&sepastore->orthogonalities, newsize) ); SCIP_ALLOC( BMSreallocMemoryArray(&sepastore->scores, newsize) ); sepastore->cutssize = newsize; } assert(num <= sepastore->cutssize); return SCIP_OKAY; }
/** append diveset to heuristic array of divesets */ static SCIP_RETCODE heurAddDiveset( SCIP_HEUR* heur, /**< the heuristic to which this dive setting belongs */ SCIP_DIVESET* diveset /**< pointer to the freshly created diveset */ ) { assert(heur != NULL); assert(diveset != NULL); assert(diveset->heur == NULL); diveset->heur = heur; if( heur->divesets == NULL ) { assert(heur->ndivesets == 0); SCIP_ALLOC( BMSallocMemoryArray(&heur->divesets, 1) ); } else { assert(heur->ndivesets > 0); SCIP_ALLOC( BMSreallocMemoryArray(&heur->divesets, heur->ndivesets + 1) ); /*lint !e776 I expect no overflow here */ } /* append diveset to the end of the array */ heur->divesets[heur->ndivesets] = diveset; heur->ndivesets++; return SCIP_OKAY; }
/** Read the value of an attribute from the input stream. * * The value has to be between two " or ' (the other character is then valid as well). The function * returns a pointer to allocated memory containing the value or it returns NULL in case of an * error. */ static char* get_attrval( PPOS* ppos ) { char* attr = NULL; int c; int stop; size_t len = 0; size_t size = 0; assert(ppos != NULL); /* The following is not allowed according to the specification (the value has to be directly * after the equation sign). */ c = skip_space(ppos); if ((c != '"') && (c != '\'')) { xml_error(ppos, "Atribute value does not start with \" or \'"); return NULL; } stop = c; for(;;) { if (len == size) { size += ATTR_EXT_SIZE; if ( attr == NULL ) { ALLOC_ABORT( BMSallocMemoryArray(&attr, size) ); } else { ALLOC_ABORT( BMSreallocMemoryArray(&attr, size) ); } } assert(attr != NULL); assert(size > len); c = getsymbol(ppos); if ((c == stop) || (c == EOF)) break; attr[len++] = (char)c; } if (c != EOF) attr[len] = '\0'; else { BMSfreeMemoryArray(&attr); attr = NULL; } return attr; }
/** Get name of a TAG or attribute from the input stream. * * Either it returns a pointer to allocated memory which contains the name or it returns NULL if * there is some error. */ static char* get_name( PPOS* ppos ) { char* name = NULL; size_t size = 0; size_t len = 0; int c; assert(ppos != NULL); c = getsymbol(ppos); if (!isalpha(c) && (c != '_') && (c != ':')) { xml_error(ppos, "Name starting with illegal charater"); return NULL; } /* The following is wrong: Here almost all characters that we casted to unicode are feasible */ while (isalnum(c) || (c == '_') || (c == ':') || (c == '.') || (c == '-')) { if (len + 1 >= size) { size += NAME_EXT_SIZE; if ( name == NULL ) { ALLOC_ABORT( BMSallocMemoryArray(&name, size) ); } else { ALLOC_ABORT( BMSreallocMemoryArray(&name, size) ); } } assert(name != NULL); assert(size > len); name[len++] = (char)c; c = getsymbol(ppos); } if (c != EOF) ungetsymbol(ppos, c); assert(name != NULL); if (len == 0) { BMSfreeMemoryArray(&name); name = NULL; } else name[len] = '\0'; return name; }
/** resizes vars and score arrays to be able to store at least num entries */ static SCIP_RETCODE pricestoreEnsureVarsMem( SCIP_PRICESTORE* pricestore, /**< pricing storage */ SCIP_SET* set, /**< global SCIP settings */ int num /**< minimal number of slots in array */ ) { assert(pricestore != NULL); assert(set != NULL); if( num > pricestore->varssize ) { int newsize; newsize = SCIPsetCalcMemGrowSize(set, num); SCIP_ALLOC( BMSreallocMemoryArray(&pricestore->vars, newsize) ); SCIP_ALLOC( BMSreallocMemoryArray(&pricestore->scores, newsize) ); pricestore->varssize = newsize; } assert(num <= pricestore->varssize); return SCIP_OKAY; }
/** ensures, that the clique hash table is able to store at least the given number of cliques */ static void ensureCliquehashSize( CLIQUEHASH* cliquehash, /**< clique hash table */ int num /**< minimal number of cliques to store */ ) { assert(cliquehash != NULL); if( num > cliquehash->cliquessize ) { int newsize; newsize = 2*cliquehash->cliquessize; if( num > newsize ) newsize = num; ALLOC_ABORT( BMSreallocMemoryArray(&cliquehash->cliques, newsize) ); cliquehash->cliquessize = newsize; } assert(cliquehash->cliquessize >= num); }
/** allocates the next unused buffer */ SCIP_RETCODE SCIPbufferAllocMem( SCIP_BUFFER* buffer, /**< memory buffer storage */ SCIP_SET* set, /**< global SCIP settings */ void** ptr, /**< pointer to store the allocated memory buffer */ int size /**< minimal required size of the buffer */ ) { #ifndef SCIP_NOBUFFERMEM int bufnum; assert(buffer != NULL); assert(buffer->firstfree <= buffer->ndata); assert(ptr != NULL); assert(size >= 0); /* allocate minimal 1 byte */ if( size == 0 ) size = 1; /* check, if we need additional buffers */ if( buffer->firstfree == buffer->ndata ) { int newsize; int i; /* create additional buffers */ newsize = SCIPsetCalcMemGrowSize(set, buffer->firstfree+1); SCIP_ALLOC( BMSreallocMemoryArray(&buffer->data, newsize) ); SCIP_ALLOC( BMSreallocMemoryArray(&buffer->size, newsize) ); SCIP_ALLOC( BMSreallocMemoryArray(&buffer->used, newsize) ); for( i = buffer->ndata; i < newsize; ++i ) { buffer->data[i] = NULL; buffer->size[i] = 0; buffer->used[i] = FALSE; } buffer->ndata = newsize; } assert(buffer->firstfree < buffer->ndata); /* check, if the current buffer is large enough */ bufnum = buffer->firstfree; assert(!buffer->used[bufnum]); if( buffer->size[bufnum] < size ) { int newsize; /* enlarge buffer */ newsize = SCIPsetCalcMemGrowSize(set, size); SCIP_ALLOC( BMSreallocMemorySize(&buffer->data[bufnum], newsize) ); buffer->size[bufnum] = newsize; } assert(buffer->size[bufnum] >= size); *ptr = buffer->data[bufnum]; buffer->used[bufnum] = TRUE; buffer->firstfree++; SCIPdebugMessage("allocated buffer %d/%d at %p of size %d (required size: %d) for pointer %p\n", bufnum, buffer->ndata, buffer->data[bufnum], buffer->size[bufnum], size, (void*)ptr); #else SCIP_ALLOC( BMSallocMemorySize(ptr, size) ); #endif return SCIP_OKAY; }
/* Handles PCDATA */ static void proc_pcdata( PPOS* ppos /**< input stream position */ ) { XML_NODE* node; char* data = NULL; size_t size = 0; size_t len = 0; int c; assert(ppos != NULL); assert(ppos->state == STATE_PCDATA); #ifndef SPEC_LIKE_SPACE_HANDLING if ((c = skip_space(ppos)) != EOF) ungetsymbol(ppos, c); #endif c = getsymbol(ppos); while ((c != EOF) && (c != '<')) { if (len >= size - 1) /* leave space for terminating '\0' */ { size += DATA_EXT_SIZE; if ( data == NULL ) { ALLOC_ABORT( BMSallocMemoryArray(&data, size) ); } else { ALLOC_ABORT( BMSreallocMemoryArray(&data, size) ); } } assert(data != NULL); assert(size > len + 1); data[len++] = (char)c; c = getsymbol(ppos); } if (data == NULL) { if (c == EOF) ppos->state = STATE_EOF; else if (c == '<') { ppos->state = STATE_BEFORE; ungetsymbol(ppos, c); } else { ppos->state = STATE_ERROR; } } else { assert(len < size); data[len] = '\0'; if (c == EOF) ppos->state = STATE_ERROR; else { ungetsymbol(ppos, c); if (NULL == (node = xml_new_node("#PCDATA", ppos->lineno))) { xml_error(ppos, "Can't create new node"); ppos->state = STATE_ERROR; } else { BMSduplicateMemoryArray(&node->data, data, strlen(data)+1); xml_append_child(top_pstack(ppos), node); ppos->state = STATE_BEFORE; } BMSfreeMemoryArray(&data); } } }
/** Handles a CDATA section. * * Returns a pointer to allocated memory containing the data of this section or NULL in case of an * error. */ static char* do_cdata( PPOS* ppos ) { char* data = NULL; size_t size = 0; size_t len = 0; int state = 0; int c; assert(ppos != NULL); for(;;) { c = getsymbol(ppos); if (c == EOF) break; if (c == ']') state++; else if ((c == '>') && (state >= 2)) break; else state = 0; if (len == size) { size += DATA_EXT_SIZE; if ( data == NULL ) { ALLOC_ABORT( BMSallocMemoryArray(&data, size) ); } else { ALLOC_ABORT( BMSreallocMemoryArray(&data, size) ); } } assert(data != NULL); assert(size > len); data[len++] = (char)c; } assert(data != NULL); if (c != EOF) { assert(len >= 2); data[len - 2] = '\0'; } else { BMSfreeMemoryArray(&data); data = NULL; xml_error(ppos, "Unexpected EOF in CDATA"); } return data; }
/** reads solution from given file into given arrays */ static SCIP_RETCODE readSolfile( SCIP_SET* set, /**< global SCIP settings */ const char* solfilename, /**< solution filename to read */ char*** names, /**< pointer to store the array of variable names */ SCIP_Real** vals, /**< pointer to store the array of solution values */ int* nvals, /**< pointer to store the number of non-zero elements */ int* valssize /**< pointer to store the length of the variable names and solution values arrays */ ) { FILE* file; int nonvalues; int i; assert(set != NULL); assert(solfilename != NULL); assert(names != NULL); assert(*names == NULL); assert(vals != NULL); assert(*vals == NULL); assert(nvals != NULL); assert(valssize != NULL); printf("***** debug: reading solution file <%s>\n", solfilename); /* open solution file */ file = fopen(solfilename, "r"); if( file == NULL ) { SCIPerrorMessage("cannot open solution file <%s> specified in scip/debug.h\n", solfilename); SCIPprintSysError(solfilename); return SCIP_NOFILE; } /* read data */ nonvalues = 0; *valssize = 0; while( !feof(file) ) { char buf[SCIP_MAXSTRLEN]; char name[SCIP_MAXSTRLEN]; char objstring[SCIP_MAXSTRLEN]; SCIP_Real val; int nread; if( fgets(buf, SCIP_MAXSTRLEN, file) == NULL ) { if( feof(file) ) break; else return SCIP_READERROR; } /* the lines "solution status: ..." and "objective value: ..." may preceed the solution information */ if( strncmp(buf, "solution", 8) == 0 || strncmp(buf, "objective", 9) == 0 ) { nonvalues++; continue; } /* skip empty lines */ if( strlen(buf) == 1 ) { nonvalues++; continue; } nread = sscanf(buf, "%s %lf %s\n", name, &val, objstring); if( nread < 2 ) { printf("invalid input line %d in solution file <%s>: <%s>\n", *nvals + nonvalues, SCIP_DEBUG_SOLUTION, name); fclose(file); return SCIP_READERROR; } /* allocate memory */ if( *nvals >= *valssize ) { *valssize = MAX(2 * *valssize, (*nvals)+1); SCIP_ALLOC( BMSreallocMemoryArray(names, *valssize) ); SCIP_ALLOC( BMSreallocMemoryArray(vals, *valssize) ); } assert(*nvals < *valssize); /* store solution value in sorted list */ for( i = *nvals; i > 0 && strcmp(name, (*names)[i-1]) < 0; --i ) { (*names)[i] = (*names)[i-1]; (*vals)[i] = (*vals)[i-1]; } SCIP_ALLOC( BMSduplicateMemoryArray(&(*names)[i], name, strlen(name)+1) ); SCIPdebugMessage("found variable <%s>: value <%g>\n", (*names)[i], val); (*vals)[i] = val; (*nvals)++; } debugsolval = 0.0; /* get solution value */ for( i = *nvals - 1; i >= 0; --i) { SCIP_VAR* var; var = SCIPfindVar(set->scip, (*names)[i]); if( var != NULL ) debugsolval += (*vals)[i] * SCIPvarGetObj(var); } SCIPdebugMessage("Debug Solution value is %g.\n", debugsolval); /* close file */ fclose(file); /* remember the set pointer to identify sub-MIP calls */ mainscipset = set; printf("***** debug: read %d non-zero entries\n", *nvals); return SCIP_OKAY; }
/** adds a solution value for a new variable in the transformed problem that has no original counterpart * a value can only be set if no value has been set for this variable before */ extern SCIP_RETCODE SCIPdebugAddSolVal( SCIP* scip, /**< SCIP data structure */ SCIP_VAR* var, /**< variable for which to add a value */ SCIP_Real val /**< solution value for variable */ ) { const char* varname; int i; assert(var != NULL); /* check if we are in the SCIP instance that we are debugging and not some different (subSCIP, auxiliary CIP, ...) */ if( !isSolutionInMip(scip->set) ) return SCIP_OKAY; if( SCIPvarIsOriginal(var) ) { SCIPerrorMessage("adding solution values for original variables is forbidden\n"); return SCIP_ERROR; } if( SCIPvarIsTransformedOrigvar(var) ) { SCIPerrorMessage("adding solution values for variable that are direct counterparts of original variables is forbidden\n"); return SCIP_ERROR; } /* allocate memory */ if( nsolvals >= solsize ) { solsize = MAX(2*solsize, nsolvals+1); SCIP_ALLOC( BMSreallocMemoryArray(&solnames, solsize) ); SCIP_ALLOC( BMSreallocMemoryArray(&solvals, solsize) ); } assert(nsolvals < solsize); /* store solution value in sorted list */ varname = SCIPvarGetName(var); for( i = nsolvals; i > 0 && strcmp(varname, solnames[i-1]) < 0; --i ) { solnames[i] = solnames[i-1]; solvals[i] = solvals[i-1]; } if( i > 0 && strcmp(varname, solnames[i-1]) == 0 ) { if( REALABS(solvals[i-1] - val) > 1e-9 ) { SCIPerrorMessage("already have stored different debugging solution value (%g) for variable <%s>, cannot store %g\n", solvals[i-1], varname, val); return SCIP_ERROR; } else { SCIPdebugMessage("already have stored debugging solution value %g for variable <%s>, do not store same value again\n", val, varname); for( ; i < nsolvals; ++i ) { solnames[i] = solnames[i+1]; solvals[i] = solvals[i+1]; } return SCIP_OKAY; } } /* insert new solution value */ SCIP_ALLOC( BMSduplicateMemoryArray(&solnames[i], varname, strlen(varname)+1) ); SCIPdebugMessage("add variable <%s>: value <%g>\n", solnames[i], val); solvals[i] = val; nsolvals++; /* update objective function value of debug solution */ debugsolval += solvals[i] * SCIPvarGetObj(var); SCIPdebugMessage("Debug Solution value is now %g.\n", debugsolval); return SCIP_OKAY; }