/** 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; }
/** creates a relaxation handler */ SCIP_RETCODE SCIPrelaxCreate( SCIP_RELAX** relax, /**< pointer to relaxation handler data structure */ SCIP_SET* set, /**< global SCIP settings */ SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ const char* name, /**< name of relaxation handler */ const char* desc, /**< description of relaxation handler */ int priority, /**< priority of the relaxation handler (negative: after LP, non-negative: before LP) */ int freq, /**< frequency for calling relaxation handler */ SCIP_DECL_RELAXCOPY ((*relaxcopy)), /**< copy method of relaxation handler or NULL if you don't want to copy your plugin into sub-SCIPs */ SCIP_DECL_RELAXFREE ((*relaxfree)), /**< destructor of relaxation handler */ SCIP_DECL_RELAXINIT ((*relaxinit)), /**< initialize relaxation handler */ SCIP_DECL_RELAXEXIT ((*relaxexit)), /**< deinitialize relaxation handler */ SCIP_DECL_RELAXINITSOL((*relaxinitsol)), /**< solving process initialization method of relaxation handler */ SCIP_DECL_RELAXEXITSOL((*relaxexitsol)), /**< solving process deinitialization method of relaxation handler */ SCIP_DECL_RELAXEXEC ((*relaxexec)), /**< execution method of relaxation handler */ SCIP_RELAXDATA* relaxdata /**< relaxation handler data */ ) { char paramname[SCIP_MAXSTRLEN]; char paramdesc[SCIP_MAXSTRLEN]; assert(relax != NULL); assert(name != NULL); assert(desc != NULL); assert(freq >= -1); assert(relaxexec != NULL); SCIP_ALLOC( BMSallocMemory(relax) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*relax)->name, name, strlen(name)+1) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*relax)->desc, desc, strlen(desc)+1) ); (*relax)->priority = priority; (*relax)->freq = freq; (*relax)->relaxcopy = relaxcopy; (*relax)->relaxfree = relaxfree; (*relax)->relaxinit = relaxinit; (*relax)->relaxexit = relaxexit; (*relax)->relaxinitsol = relaxinitsol; (*relax)->relaxexitsol = relaxexitsol; (*relax)->relaxexec = relaxexec; (*relax)->relaxdata = relaxdata; SCIP_CALL( SCIPclockCreate(&(*relax)->setuptime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*relax)->relaxclock, SCIP_CLOCKTYPE_DEFAULT) ); (*relax)->ncalls = 0; (*relax)->lastsolvednode = -1; (*relax)->initialized = FALSE; /* add parameters */ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "relaxing/%s/priority", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of relaxation handler <%s>", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*relax)->priority, FALSE, priority, INT_MIN/4, INT_MAX/4, paramChgdRelaxPriority, (SCIP_PARAMDATA*)(*relax)) ); /*lint !e740*/ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "relaxing/%s/freq", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency for calling relaxation handler <%s> (-1: never, 0: only in root node)", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*relax)->freq, FALSE, freq, -1, INT_MAX, NULL, NULL) ); return SCIP_OKAY; }
/** creates a reader */ SCIP_RETCODE SCIPreaderCreate( SCIP_READER** reader, /**< pointer to store reader */ const char* name, /**< name of reader */ const char* desc, /**< description of reader */ const char* extension, /**< file extension that reader processes */ SCIP_DECL_READERCOPY ((*readercopy)), /**< copy method of reader or NULL if you don't want to copy your plugin into sub-SCIPs */ SCIP_DECL_READERFREE ((*readerfree)), /**< destructor of reader */ SCIP_DECL_READERREAD ((*readerread)), /**< read method */ SCIP_DECL_READERWRITE ((*readerwrite)), /**< write method */ SCIP_READERDATA* readerdata /**< reader data */ ) { assert(reader != NULL); assert(name != NULL); assert(desc != NULL); assert(extension != NULL); SCIP_ALLOC( BMSallocMemory(reader) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*reader)->name, name, strlen(name)+1) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*reader)->desc, desc, strlen(desc)+1) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*reader)->extension, extension, strlen(extension)+1) ); (*reader)->readercopy = readercopy; (*reader)->readerfree = readerfree; (*reader)->readerread = readerread; (*reader)->readerwrite = readerwrite; (*reader)->readerdata = readerdata; /* create reading clock */ SCIP_CALL( SCIPclockCreate(&(*reader)->readingtime, SCIP_CLOCKTYPE_DEFAULT) ); 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; }
/** creates a variable pricer * To use the variable pricer for solving a problem, it first has to be activated with a call to SCIPactivatePricer(). */ SCIP_RETCODE SCIPpricerCreate( SCIP_PRICER** pricer, /**< pointer to variable pricer data structure */ SCIP_SET* set, /**< global SCIP settings */ BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ const char* name, /**< name of variable pricer */ const char* desc, /**< description of variable pricer */ int priority, /**< priority of the variable pricer */ SCIP_Bool delay, /**< should the pricer be delayed until no other pricers or already existing * problem variables with negative reduced costs are found */ SCIP_DECL_PRICERCOPY ((*pricercopy)), /**< copy method of pricer or NULL if you don't want to copy your plugin into sub-SCIPs */ SCIP_DECL_PRICERFREE ((*pricerfree)), /**< destructor of variable pricer */ SCIP_DECL_PRICERINIT ((*pricerinit)), /**< initialize variable pricer */ SCIP_DECL_PRICEREXIT ((*pricerexit)), /**< deinitialize variable pricer */ SCIP_DECL_PRICERINITSOL((*pricerinitsol)),/**< solving process initialization method of variable pricer */ SCIP_DECL_PRICEREXITSOL((*pricerexitsol)),/**< solving process deinitialization method of variable pricer */ SCIP_DECL_PRICERREDCOST((*pricerredcost)),/**< reduced cost pricing method of variable pricer for feasible LPs */ SCIP_DECL_PRICERFARKAS((*pricerfarkas)), /**< Farkas pricing method of variable pricer for infeasible LPs */ SCIP_PRICERDATA* pricerdata /**< variable pricer data */ ) { char paramname[SCIP_MAXSTRLEN]; char paramdesc[SCIP_MAXSTRLEN]; assert(pricer != NULL); assert(name != NULL); assert(desc != NULL); assert(pricerredcost != NULL); SCIP_ALLOC( BMSallocMemory(pricer) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*pricer)->name, name, strlen(name)+1) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*pricer)->desc, desc, strlen(desc)+1) ); (*pricer)->priority = priority; (*pricer)->pricercopy = pricercopy; (*pricer)->pricerfree = pricerfree; (*pricer)->pricerinit = pricerinit; (*pricer)->pricerexit = pricerexit; (*pricer)->pricerinitsol = pricerinitsol; (*pricer)->pricerexitsol = pricerexitsol; (*pricer)->pricerredcost = pricerredcost; (*pricer)->pricerfarkas = pricerfarkas; (*pricer)->pricerdata = pricerdata; SCIP_CALL( SCIPclockCreate(&(*pricer)->pricerclock, SCIP_CLOCKTYPE_DEFAULT) ); (*pricer)->ncalls = 0; (*pricer)->nvarsfound = 0; (*pricer)->delay = delay; (*pricer)->active = FALSE; (*pricer)->initialized = FALSE; /* add parameters */ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "pricers/%s/priority", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of pricer <%s>", name); SCIP_CALL( SCIPsetAddIntParam(set, blkmem, paramname, paramdesc, &(*pricer)->priority, FALSE, priority, INT_MIN/4, INT_MAX/4, paramChgdPricerPriority, (SCIP_PARAMDATA*)(*pricer)) ); /*lint !e740*/ return SCIP_OKAY; }
/** reallocates the buffer to at least the given size */ SCIP_RETCODE SCIPbufferReallocMem( SCIP_BUFFER* buffer, /**< memory buffer storage */ SCIP_SET* set, /**< global SCIP settings */ void** ptr, /**< pointer to 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); /* if the pointer doesn't exist yet, allocate it */ if( *ptr == NULL ) return SCIPbufferAllocMem(buffer, set, ptr, size); assert(buffer->firstfree >= 1); /* Search the pointer in the buffer list * Usually, buffers are allocated and freed like a stack, such that the currently used pointer is * most likely at the end of the buffer list. */ for( bufnum = buffer->firstfree-1; bufnum >= 0 && buffer->data[bufnum] != *ptr; --bufnum ) { } assert(bufnum >= 0); assert(buffer->data[bufnum] == *ptr); assert(buffer->used[bufnum]); assert(buffer->size[bufnum] >= 1); /* check if the buffer has to be enlarged */ if( size > buffer->size[bufnum] ) { int newsize; /* enlarge buffer */ newsize = SCIPsetCalcMemGrowSize(set, size); SCIP_ALLOC( BMSreallocMemorySize(&buffer->data[bufnum], newsize) ); buffer->size[bufnum] = newsize; *ptr = buffer->data[bufnum]; } assert(buffer->size[bufnum] >= size); assert(*ptr == buffer->data[bufnum]); SCIPdebugMessage("reallocated buffer %d/%d at %p to size %d (required size: %d) for pointer %p\n", bufnum, buffer->ndata, buffer->data[bufnum], buffer->size[bufnum], size, (void*)ptr); #else SCIP_ALLOC( BMSreallocMemorySize(ptr, size) ); #endif return SCIP_OKAY; }
/** creates pricing storage */ SCIP_RETCODE SCIPpricestoreCreate( SCIP_PRICESTORE** pricestore /**< pointer to store pricing storage */ ) { assert(pricestore != NULL); SCIP_ALLOC( BMSallocMemory(pricestore) ); SCIP_CALL( SCIPclockCreate(&(*pricestore)->probpricingtime, SCIP_CLOCKTYPE_DEFAULT) ); (*pricestore)->vars = NULL; (*pricestore)->scores = NULL; (*pricestore)->bdviolvars = NULL; (*pricestore)->bdviolvarslb = NULL; (*pricestore)->bdviolvarsub = NULL; (*pricestore)->varssize = 0; (*pricestore)->nvars = 0; (*pricestore)->bdviolvarssize = 0; (*pricestore)->nbdviolvars = 0; (*pricestore)->naddedbdviolvars = 0; (*pricestore)->nprobpricings = 0; (*pricestore)->nprobvarsfound = 0; (*pricestore)->nvarsfound = 0; (*pricestore)->nvarsapplied = 0; (*pricestore)->initiallp = FALSE; return SCIP_OKAY; }
/** creates block memory structures */ SCIP_RETCODE SCIPmemCreate( SCIP_MEM** mem /**< pointer to block memory structure */ ) { assert(mem != NULL); SCIP_ALLOC( BMSallocMemory(mem) ); SCIP_ALLOC( (*mem)->setmem = BMScreateBlockMemory(1, 10) ); SCIP_ALLOC( (*mem)->probmem = BMScreateBlockMemory(1, 10) ); SCIPdebugMessage("created setmem block memory at <%p>\n", (void*)(*mem)->setmem); SCIPdebugMessage("created probmem block memory at <%p>\n", (void*)(*mem)->probmem); return SCIP_OKAY; }
/** activates all display lines fitting in the display w.r. to priority */ SCIP_RETCODE SCIPdispAutoActivate( SCIP_SET* set /**< global SCIP settings */ ) { SCIP_DISP** disps; int totalwidth; int width; int i; assert(set != NULL); /* sort display columns w.r. to their priority */ SCIP_ALLOC( BMSduplicateMemoryArray(&disps, set->disps, set->ndisps) ); SCIPsortPtr((void**)disps, dispComp, set->ndisps); totalwidth = 0; /* first activate all columns with display status ON */ for( i = 0; i < set->ndisps; ++i ) { width = disps[i]->width; if( disps[i]->stripline ) width++; if( disps[i]->dispstatus == SCIP_DISPSTATUS_ON ) { disps[i]->active = TRUE; totalwidth += width; } else disps[i]->active = FALSE; } /* beginning with highest priority display column, activate AUTO columns as long as it fits into display width */ for( i = 0; i < set->ndisps; ++i ) { if( disps[i]->dispstatus == SCIP_DISPSTATUS_AUTO ) { assert(!disps[i]->active); width = disps[i]->width; if( disps[i]->stripline ) width++; if( totalwidth + width <= set->disp_width ) { disps[i]->active = TRUE; totalwidth += width; } } } /* free temporary memory */ BMSfreeMemoryArray(&disps); return SCIP_OKAY; }
/** Creates and captures a message handler which deals with warning, information, and dialog (interactive shell) methods. * * @note The message handler does not handle error messages; see SCIPmessageSetErrorPrinting() */ SCIP_RETCODE SCIPmessagehdlrCreate( SCIP_MESSAGEHDLR** messagehdlr, /**< pointer to store the message handler */ SCIP_Bool bufferedoutput, /**< should the output be buffered up to the next newline? */ const char* filename, /**< name of log file, or NULL for no log */ SCIP_Bool quiet, /**< should screen messages be suppressed? */ SCIP_DECL_MESSAGEWARNING((*messagewarning)),/**< warning message print method of message handler */ SCIP_DECL_MESSAGEDIALOG((*messagedialog)),/**< dialog message print method of message handler */ SCIP_DECL_MESSAGEINFO ((*messageinfo)), /**< info message print method of message handler */ SCIP_DECL_MESSAGEHDLRFREE((*messagehdlrfree)), /**< destructor of message handler to free message handler data */ SCIP_MESSAGEHDLRDATA* messagehdlrdata /**< message handler data */ ) { SCIP_ALLOC( BMSallocMemory(messagehdlr) ); (*messagehdlr)->messagewarning = messagewarning; (*messagehdlr)->messagedialog = messagedialog; (*messagehdlr)->messageinfo = messageinfo; (*messagehdlr)->messagehdlrfree = messagehdlrfree; (*messagehdlr)->messagehdlrdata = messagehdlrdata; (*messagehdlr)->warningbuffer = NULL; (*messagehdlr)->dialogbuffer = NULL; (*messagehdlr)->infobuffer = NULL; (*messagehdlr)->warningbufferlen = 0; (*messagehdlr)->dialogbufferlen = 0; (*messagehdlr)->infobufferlen = 0; (*messagehdlr)->nuses = 1; (*messagehdlr)->quiet = quiet; messagehdlrOpenLogfile(*messagehdlr, filename); /* allocate buffer for buffered output */ if( bufferedoutput ) { SCIP_ALLOC( BMSallocMemoryArray(&(*messagehdlr)->warningbuffer, SCIP_MAXSTRLEN) ); /*lint !e506*/ SCIP_ALLOC( BMSallocMemoryArray(&(*messagehdlr)->dialogbuffer, SCIP_MAXSTRLEN) ); /*lint !e506*/ SCIP_ALLOC( BMSallocMemoryArray(&(*messagehdlr)->infobuffer, SCIP_MAXSTRLEN) ); /*lint !e506*/ (*messagehdlr)->warningbuffer[0] = '\0'; (*messagehdlr)->dialogbuffer[0] = '\0'; (*messagehdlr)->infobuffer[0] = '\0'; } return SCIP_OKAY; }
/** creates global relaxation data */ SCIP_RETCODE SCIPrelaxationCreate( SCIP_RELAXATION** relaxation /**< global relaxation data */ ) { assert(relaxation != NULL); SCIP_ALLOC( BMSallocMemory(relaxation) ); (*relaxation)->relaxsolobjval = 0.0; (*relaxation)->relaxsolvalid = FALSE; (*relaxation)->relaxsolzero = TRUE; return SCIP_OKAY; }
/** 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; }
/** creates block and buffer memory structures */ SCIP_RETCODE SCIPmemCreate( SCIP_MEM** mem /**< pointer to block and buffer memory structure */ ) { assert(mem != NULL); SCIP_ALLOC( BMSallocMemory(mem) ); /* alloc block memory */ SCIP_ALLOC( (*mem)->setmem = BMScreateBlockMemory(1, 10) ); SCIP_ALLOC( (*mem)->probmem = BMScreateBlockMemory(1, 10) ); /* alloc memory buffers */ SCIP_ALLOC( (*mem)->buffer = BMScreateBufferMemory(SCIP_DEFAULT_MEM_ARRAYGROWFAC, SCIP_DEFAULT_MEM_ARRAYGROWINIT, FALSE) ); SCIP_ALLOC( (*mem)->cleanbuffer = BMScreateBufferMemory(SCIP_DEFAULT_MEM_ARRAYGROWFAC, SCIP_DEFAULT_MEM_ARRAYGROWINIT, TRUE) ); SCIPdebugMessage("created setmem block memory at <%p>\n", (void*)(*mem)->setmem); SCIPdebugMessage("created probmem block memory at <%p>\n", (void*)(*mem)->probmem); SCIPdebugMessage("created buffer memory at <%p>\n", (void*)(*mem)->buffer); SCIPdebugMessage("created clean buffer memory at <%p>\n", (void*)(*mem)->cleanbuffer); return SCIP_OKAY; }
/** creates memory buffer storage */ SCIP_RETCODE SCIPbufferCreate( SCIP_BUFFER** buffer /**< pointer to memory buffer storage */ ) { assert(buffer != NULL); SCIP_ALLOC( BMSallocMemory(buffer) ); (*buffer)->data = NULL; (*buffer)->size = NULL; (*buffer)->used = NULL; (*buffer)->ndata = 0; (*buffer)->firstfree = 0; return SCIP_OKAY; }
/** creates problem statistics data */ SCIP_RETCODE SCIPstatCreate( SCIP_STAT** stat, /**< pointer to problem statistics data */ BMS_BLKMEM* blkmem, /**< block memory */ SCIP_SET* set, /**< global SCIP settings */ SCIP_MESSAGEHDLR* messagehdlr /**< message handler */ ) { assert(stat != NULL); assert(set != NULL); SCIP_ALLOC( BMSallocMemory(stat) ); SCIP_CALL( SCIPclockCreate(&(*stat)->solvingtime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->presolvingtime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->primallptime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->duallptime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->lexduallptime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->barrierlptime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->divinglptime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->strongbranchtime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->conflictlptime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->lpsoltime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->pseudosoltime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->sbsoltime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->nodeactivationtime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->nlpsoltime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->copyclock, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*stat)->strongpropclock, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPhistoryCreate(&(*stat)->glbhistory, blkmem) ); SCIP_CALL( SCIPhistoryCreate(&(*stat)->glbhistorycrun, blkmem) ); SCIP_CALL( SCIPvbcCreate(&(*stat)->vbc, messagehdlr) ); (*stat)->status = SCIP_STATUS_UNKNOWN; (*stat)->marked_nvaridx = 0; (*stat)->marked_ncolidx = 0; (*stat)->marked_nrowidx = 0; (*stat)->userinterrupt = FALSE; (*stat)->userrestart = FALSE; (*stat)->inrestart = FALSE; (*stat)->collectvarhistory = TRUE; (*stat)->subscipdepth = 0; SCIPstatReset(*stat, set); return SCIP_OKAY; }
/** creates VBC Tool data structure */ SCIP_RETCODE SCIPvbcCreate( SCIP_VBC** vbc, /**< pointer to store the VBC information */ SCIP_MESSAGEHDLR* messagehdlr /**< message handler */ ) { SCIP_ALLOC( BMSallocMemory(vbc) ); (*vbc)->file = NULL; (*vbc)->messagehdlr = messagehdlr; (*vbc)->nodenum = NULL; (*vbc)->timestep = 0; (*vbc)->lastnode = NULL; (*vbc)->lastcolor = SCIP_VBCCOLOR_NONE; (*vbc)->userealtime = FALSE; return SCIP_OKAY; }
/** creates visualization data structure */ SCIP_RETCODE SCIPvisualCreate( SCIP_VISUAL** visual, /**< pointer to store visualization information */ SCIP_MESSAGEHDLR* messagehdlr /**< message handler */ ) { SCIP_ALLOC( BMSallocMemory(visual) ); (*visual)->vbcfile = NULL; (*visual)->bakfile = NULL; (*visual)->messagehdlr = messagehdlr; (*visual)->nodenum = NULL; (*visual)->timestep = 0; (*visual)->lastnode = NULL; (*visual)->lastcolor = SCIP_VBCCOLOR_NONE; (*visual)->userealtime = FALSE; return SCIP_OKAY; }
/** creates separation storage */ SCIP_RETCODE SCIPsepastoreCreate( SCIP_SEPASTORE** sepastore /**< pointer to store separation storage */ ) { assert(sepastore != NULL); SCIP_ALLOC( BMSallocMemory(sepastore) ); (*sepastore)->cuts = NULL; (*sepastore)->efficacies = NULL; (*sepastore)->objparallelisms = NULL; (*sepastore)->orthogonalities = NULL; (*sepastore)->scores = NULL; (*sepastore)->cutssize = 0; (*sepastore)->ncuts = 0; (*sepastore)->nforcedcuts = 0; (*sepastore)->ncutsfound = 0; (*sepastore)->ncutsfoundround = 0; (*sepastore)->ncutsapplied = 0; (*sepastore)->initiallp = FALSE; (*sepastore)->forcecuts = FALSE; return SCIP_OKAY; }
/** creates a separator */ SCIP_RETCODE SCIPsepaCreate( SCIP_SEPA** sepa, /**< pointer to separator data structure */ SCIP_SET* set, /**< global SCIP settings */ SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ const char* name, /**< name of separator */ const char* desc, /**< description of separator */ int priority, /**< priority of separator (>= 0: before, < 0: after constraint handlers) */ int freq, /**< frequency for calling separator */ SCIP_Real maxbounddist, /**< maximal relative distance from current node's dual bound to primal bound compared * to best node's dual bound for applying separation */ SCIP_Bool usessubscip, /**< does the separator use a secondary SCIP instance? */ SCIP_Bool delay, /**< should separator be delayed, if other separators found cuts? */ SCIP_DECL_SEPACOPY ((*sepacopy)), /**< copy method of separator or NULL if you don't want to copy your plugin into sub-SCIPs */ SCIP_DECL_SEPAFREE ((*sepafree)), /**< destructor of separator */ SCIP_DECL_SEPAINIT ((*sepainit)), /**< initialize separator */ SCIP_DECL_SEPAEXIT ((*sepaexit)), /**< deinitialize separator */ SCIP_DECL_SEPAINITSOL ((*sepainitsol)), /**< solving process initialization method of separator */ SCIP_DECL_SEPAEXITSOL ((*sepaexitsol)), /**< solving process deinitialization method of separator */ SCIP_DECL_SEPAEXECLP ((*sepaexeclp)), /**< LP solution separation method of separator */ SCIP_DECL_SEPAEXECSOL ((*sepaexecsol)), /**< arbitrary primal solution separation method of separator */ SCIP_SEPADATA* sepadata /**< separator data */ ) { char paramname[SCIP_MAXSTRLEN]; char paramdesc[SCIP_MAXSTRLEN]; assert(sepa != NULL); assert(name != NULL); assert(desc != NULL); assert(freq >= -1); assert(0.0 <= maxbounddist && maxbounddist <= 1.0); assert(sepaexeclp != NULL || sepaexecsol != NULL); SCIP_ALLOC( BMSallocMemory(sepa) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*sepa)->name, name, strlen(name)+1) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*sepa)->desc, desc, strlen(desc)+1) ); (*sepa)->priority = priority; (*sepa)->freq = freq; (*sepa)->maxbounddist = maxbounddist; (*sepa)->usessubscip = usessubscip; (*sepa)->sepacopy = sepacopy; (*sepa)->sepafree = sepafree; (*sepa)->sepainit = sepainit; (*sepa)->sepaexit = sepaexit; (*sepa)->sepainitsol = sepainitsol; (*sepa)->sepaexitsol = sepaexitsol; (*sepa)->sepaexeclp = sepaexeclp; (*sepa)->sepaexecsol = sepaexecsol; (*sepa)->sepadata = sepadata; SCIP_CALL( SCIPclockCreate(&(*sepa)->setuptime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*sepa)->sepaclock, SCIP_CLOCKTYPE_DEFAULT) ); (*sepa)->lastsepanode = -1; (*sepa)->ncalls = 0; (*sepa)->ncutoffs = 0; (*sepa)->ncutsfound = 0; (*sepa)->ncutsapplied = 0; (*sepa)->nconssfound = 0; (*sepa)->ndomredsfound = 0; (*sepa)->ncallsatnode = 0; (*sepa)->ncutsfoundatnode = 0; (*sepa)->lpwasdelayed = FALSE; (*sepa)->solwasdelayed = FALSE; (*sepa)->initialized = FALSE; /* add parameters */ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "separating/%s/priority", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of separator <%s>", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*sepa)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4, paramChgdSepaPriority, (SCIP_PARAMDATA*)(*sepa)) ); /*lint !e740*/ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "separating/%s/freq", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency for calling separator <%s> (-1: never, 0: only in root node)", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*sepa)->freq, FALSE, freq, -1, INT_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "separating/%s/maxbounddist", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for applying separator <%s> (0.0: only on current best node, 1.0: on all nodes)", name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*sepa)->maxbounddist, TRUE, maxbounddist, 0.0, 1.0, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "separating/%s/delay", name); SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname, "should separator be delayed, if other separators found cuts?", &(*sepa)->delay, TRUE, delay, NULL, NULL) ); /*lint !e740*/ return SCIP_OKAY; }
/** 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; }
/** creates a display column */ SCIP_RETCODE SCIPdispCreate( SCIP_DISP** disp, /**< pointer to store display column */ SCIP_SET* set, /**< global SCIP settings */ SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ const char* name, /**< name of display column */ const char* desc, /**< description of display column */ const char* header, /**< head line of display column */ SCIP_DISPSTATUS dispstatus, /**< display activation status of display column */ SCIP_DECL_DISPCOPY ((*dispcopy)), /**< copy method of display column or NULL if you don't want to copy your plugin into sub-SCIPs */ SCIP_DECL_DISPFREE ((*dispfree)), /**< destructor of display column */ SCIP_DECL_DISPINIT ((*dispinit)), /**< initialize display column */ SCIP_DECL_DISPEXIT ((*dispexit)), /**< deinitialize display column */ SCIP_DECL_DISPINITSOL ((*dispinitsol)), /**< solving process initialization method of display column */ SCIP_DECL_DISPEXITSOL ((*dispexitsol)), /**< solving process deinitialization method of display column */ SCIP_DECL_DISPOUTPUT ((*dispoutput)), /**< output method */ SCIP_DISPDATA* dispdata, /**< display column data */ int width, /**< width of display column (no. of chars used) */ int priority, /**< priority of display column */ int position, /**< relative position of display column */ SCIP_Bool stripline /**< should the column be separated with a line from its right neighbor? */ ) { char paramname[SCIP_MAXSTRLEN]; char paramdesc[SCIP_MAXSTRLEN]; assert(disp != NULL); assert(name != NULL); assert(desc != NULL); assert(header != NULL); assert(dispoutput != NULL); assert(width >= 0); SCIP_ALLOC( BMSallocMemory(disp) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*disp)->name, name, strlen(name)+1) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*disp)->desc, desc, strlen(desc)+1) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*disp)->header, header, strlen(header)+1) ); (*disp)->dispstatus = dispstatus; (*disp)->dispcopy = dispcopy; (*disp)->dispfree = dispfree; (*disp)->dispinit = dispinit; (*disp)->dispexit = dispexit; (*disp)->dispinitsol = dispinitsol; (*disp)->dispexitsol = dispexitsol; (*disp)->dispoutput = dispoutput; (*disp)->dispdata = dispdata; (*disp)->width = width; (*disp)->priority = priority; (*disp)->position = position; (*disp)->stripline = stripline; (*disp)->initialized = FALSE; (*disp)->active = (dispstatus == SCIP_DISPSTATUS_ON); /* add parameters */ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "display/%s/active", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "display activation status of display column <%s> (0: off, 1: auto, 2:on)", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, (int*)(&(*disp)->dispstatus), FALSE, (int)dispstatus, 0, 2, SCIPparamChgdDispActive, NULL) ); return SCIP_OKAY; }
/** creates a tree compression */ SCIP_RETCODE SCIPcomprCreate( SCIP_COMPR** compr, /**< pointer to tree compression data structure */ SCIP_SET* set, /**< global SCIP settings */ SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ const char* name, /**< name of tree compression */ const char* desc, /**< description of tree compression */ int priority, /**< priority of the tree compression */ int minnnodes, /**< minimal number of nodes for calling compression */ SCIP_DECL_COMPRCOPY ((*comprcopy)), /**< copy method of tree compression or NULL if you don't want to copy your plugin into sub-SCIPs */ SCIP_DECL_COMPRFREE ((*comprfree)), /**< destructor of tree compression */ SCIP_DECL_COMPRINIT ((*comprinit)), /**< initialize tree compression */ SCIP_DECL_COMPREXIT ((*comprexit)), /**< deinitialize tree compression */ SCIP_DECL_COMPRINITSOL ((*comprinitsol)), /**< solving process initialization method of tree compression */ SCIP_DECL_COMPREXITSOL ((*comprexitsol)), /**< solving process deinitialization method of tree compression */ SCIP_DECL_COMPREXEC ((*comprexec)), /**< execution method of tree compression */ SCIP_COMPRDATA* comprdata /**< tree compression data */ ) { char paramname[SCIP_MAXSTRLEN]; char paramdesc[SCIP_MAXSTRLEN]; assert(compr != NULL); assert(name != NULL); assert(desc != NULL); assert(comprexec != NULL); SCIP_ALLOC( BMSallocMemory(compr) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*compr)->name, name, strlen(name)+1) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*compr)->desc, desc, strlen(desc)+1) ); (*compr)->priority = priority; (*compr)->minnnodes = minnnodes; (*compr)->comprcopy = comprcopy; (*compr)->comprfree = comprfree; (*compr)->comprinit = comprinit; (*compr)->comprexit = comprexit; (*compr)->comprinitsol = comprinitsol; (*compr)->comprexitsol = comprexitsol; (*compr)->comprexec = comprexec; (*compr)->comprdata = comprdata; SCIP_CALL( SCIPclockCreate(&(*compr)->setuptime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*compr)->comprclock, SCIP_CLOCKTYPE_DEFAULT) ); (*compr)->ncalls = 0; (*compr)->nfound = 0; (*compr)->rate = 0.0; (*compr)->initialized = FALSE; (*compr)->nnodes = 0; (*compr)->loi = 0.0; /* add parameters */ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "compression/%s/priority", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of compression <%s>", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*compr)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4, paramChgdComprPriority, (SCIP_PARAMDATA*)(*compr)) ); /*lint !e740*/ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "compression/%s/minnleaves", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "minimal number of leave nodes for calling tree compression <%s>", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*compr)->minnnodes, FALSE, minnnodes, 1, INT_MAX, NULL, NULL) ); return SCIP_OKAY; }
/** creates a primal heuristic */ SCIP_RETCODE SCIPheurCreate( SCIP_HEUR** heur, /**< pointer to primal heuristic data structure */ SCIP_SET* set, /**< global SCIP settings */ SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ const char* name, /**< name of primal heuristic */ const char* desc, /**< description of primal heuristic */ char dispchar, /**< display character of primal heuristic */ int priority, /**< priority of the primal heuristic */ int freq, /**< frequency for calling primal heuristic */ int freqofs, /**< frequency offset for calling primal heuristic */ int maxdepth, /**< maximal depth level to call heuristic at (-1: no limit) */ unsigned int timingmask, /**< positions in the node solving loop where heuristic should be executed */ SCIP_Bool usessubscip, /**< does the heuristic use a secondary SCIP instance? */ SCIP_DECL_HEURCOPY ((*heurcopy)), /**< copy method of primal heuristic or NULL if you don't want to copy your plugin into sub-SCIPs */ SCIP_DECL_HEURFREE ((*heurfree)), /**< destructor of primal heuristic */ SCIP_DECL_HEURINIT ((*heurinit)), /**< initialize primal heuristic */ SCIP_DECL_HEUREXIT ((*heurexit)), /**< deinitialize primal heuristic */ SCIP_DECL_HEURINITSOL ((*heurinitsol)), /**< solving process initialization method of primal heuristic */ SCIP_DECL_HEUREXITSOL ((*heurexitsol)), /**< solving process deinitialization method of primal heuristic */ SCIP_DECL_HEUREXEC ((*heurexec)), /**< execution method of primal heuristic */ SCIP_HEURDATA* heurdata /**< primal heuristic data */ ) { char paramname[SCIP_MAXSTRLEN]; char paramdesc[SCIP_MAXSTRLEN]; assert(heur != NULL); assert(name != NULL); assert(desc != NULL); assert(freq >= -1); assert(freqofs >= 0); assert(heurexec != NULL); SCIP_ALLOC( BMSallocMemory(heur) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*heur)->name, name, strlen(name)+1) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*heur)->desc, desc, strlen(desc)+1) ); (*heur)->dispchar = dispchar; (*heur)->priority = priority; (*heur)->freq = freq; (*heur)->freqofs = freqofs; (*heur)->maxdepth = maxdepth; (*heur)->delaypos = -1; (*heur)->timingmask = timingmask; (*heur)->usessubscip = usessubscip; (*heur)->heurcopy = heurcopy; (*heur)->heurfree = heurfree; (*heur)->heurinit = heurinit; (*heur)->heurexit = heurexit; (*heur)->heurinitsol = heurinitsol; (*heur)->heurexitsol = heurexitsol; (*heur)->heurexec = heurexec; (*heur)->heurdata = heurdata; SCIP_CALL( SCIPclockCreate(&(*heur)->setuptime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*heur)->heurclock, SCIP_CLOCKTYPE_DEFAULT) ); (*heur)->ncalls = 0; (*heur)->nsolsfound = 0; (*heur)->nbestsolsfound = 0; (*heur)->initialized = FALSE; (*heur)->divesets = NULL; (*heur)->ndivesets = 0; /* add parameters */ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/priority", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of heuristic <%s>", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*heur)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4, paramChgdHeurPriority, (SCIP_PARAMDATA*)(*heur)) ); /*lint !e740*/ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/freq", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency for calling primal heuristic <%s> (-1: never, 0: only at depth freqofs)", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*heur)->freq, FALSE, freq, -1, INT_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/freqofs", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency offset for calling primal heuristic <%s>", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*heur)->freqofs, FALSE, freqofs, 0, INT_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdepth", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "maximal depth level to call primal heuristic <%s> (-1: no limit)", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*heur)->maxdepth, TRUE, maxdepth, -1, INT_MAX, NULL, NULL) ); return SCIP_OKAY; }
/** writes problem data to file with given reader or returns SCIP_DIDNOTRUN */ SCIP_RETCODE SCIPreaderWrite( SCIP_READER* reader, /**< reader */ SCIP_PROB* prob, /**< problem data */ SCIP_SET* set, /**< global SCIP settings */ FILE* file, /**< output file (or NULL for standard output) */ const char* extension, /**< file format */ SCIP_Bool genericnames, /**< using generic variable and constraint names? */ SCIP_RESULT* result /**< pointer to store the result of the callback method */ ) { SCIP_RETCODE retcode; assert(reader != NULL); assert(set != NULL); assert(extension != NULL); assert(result != NULL); /* check, if reader is applicable on the given file */ if( readerIsApplicable(reader, extension) && reader->readerwrite != NULL ) { SCIP_VAR** vars; int nvars; SCIP_VAR** fixedvars; int nfixedvars; SCIP_CONS** conss; int nconss; int i; SCIP_CONS* cons; char* name; const char* consname; const char** varnames; const char** fixedvarnames; const char** consnames; varnames = NULL; fixedvarnames = NULL; consnames = NULL; vars = prob->vars; nvars = prob->nvars; fixedvars = prob->fixedvars; nfixedvars = prob->nfixedvars; /* case of the transformed problem, we want to write currently valid problem */ if( prob->transformed ) { SCIP_CONSHDLR** conshdlrs; int nconshdlrs; conshdlrs = set->conshdlrs; nconshdlrs = set->nconshdlrs; /* collect number of constraints which have to be enforced; these are the constraints which currency (locally) * enabled; these also includes the local constraints */ nconss = 0; for( i = 0; i < nconshdlrs; ++i ) { /* check if all constraints of the constraint handler should be written */ if( set->write_allconss ) nconss += SCIPconshdlrGetNConss(conshdlrs[i]); else nconss += SCIPconshdlrGetNEnfoConss(conshdlrs[i]); } SCIPdebugMessage("Writing %d constraints.\n", nconss); SCIP_ALLOC( BMSallocMemoryArray(&conss, nconss) ); /* copy the constraints */ nconss = 0; for( i = 0; i < nconshdlrs; ++i ) { SCIP_CONS** conshdlrconss; int nconshdlrconss; int c; /* check if all constraints of the constraint handler should be written */ if( set->write_allconss ) { conshdlrconss = SCIPconshdlrGetConss(conshdlrs[i]); nconshdlrconss = SCIPconshdlrGetNConss(conshdlrs[i]); } else { conshdlrconss = SCIPconshdlrGetEnfoConss(conshdlrs[i]); nconshdlrconss = SCIPconshdlrGetNEnfoConss(conshdlrs[i]); } SCIPdebugMessage("Conshdlr <%s> has %d constraints to write from all in all %d constraints.\n", SCIPconshdlrGetName(conshdlrs[i]), nconshdlrconss, SCIPconshdlrGetNConss(conshdlrs[i])); for( c = 0; c < nconshdlrconss; ++c ) { conss[nconss] = conshdlrconss[c]; nconss++; } } } else { conss = prob->conss; nconss = prob->nconss; } if( genericnames ) { SCIP_VAR* var; int size; /* save variable and constraint names and replace these names by generic names */ /* allocate memory for saving the original variable and constraint names */ SCIP_ALLOC( BMSallocMemoryArray(&varnames, nvars) ); SCIP_ALLOC( BMSallocMemoryArray(&fixedvarnames, nfixedvars) ); SCIP_ALLOC( BMSallocMemoryArray(&consnames, nconss) ); /* compute length of the generic variable names: * - nvars + 1 to avoid log of zero * - +3 (zero at end + 'x' + 1 because we round down) * Example: 10 -> need 4 chars ("x10\0") */ size = (int) log10(nvars+1.0) + 3; for( i = 0; i < nvars; ++i ) { var = vars[i]; varnames[i] = SCIPvarGetName(var); SCIP_ALLOC( BMSallocMemoryArray(&name, size) ); (void) SCIPsnprintf(name, size, "x%d", i + set->write_genoffset); SCIPvarSetNamePointer(var, name); } /* compute length of the generic variable names */ size = (int) log10(nfixedvars+1.0) + 3; for( i = 0; i < nfixedvars; ++i ) { var = fixedvars[i]; fixedvarnames[i] = SCIPvarGetName(var); SCIP_ALLOC( BMSallocMemoryArray(&name, size) ); (void) SCIPsnprintf(name, size, "y%d", i); SCIPvarSetNamePointer(var, name); } /* compute length of the generic constraint names */ size = (int) log10(nconss+1.0) + 3; for( i = 0; i < nconss; ++i ) { cons = conss[i]; consnames[i] = SCIPconsGetName(cons); SCIP_ALLOC( BMSallocMemoryArray(&name, size) ); (void) SCIPsnprintf(name, size, "c%d", i); SCIPconsSetNamePointer(cons, name); } } /* call reader to write problem */ retcode = reader->readerwrite(set->scip, reader, file, prob->name, prob->probdata, prob->transformed, prob->transformed ? SCIP_OBJSENSE_MINIMIZE : prob->objsense, prob->objscale, prob->objoffset, vars, nvars, prob->nbinvars, prob->nintvars, prob->nimplvars, prob->ncontvars, fixedvars, nfixedvars, prob->startnvars, conss, nconss, prob->maxnconss, prob->startnconss, genericnames, result); /* reset variable and constraint names to original names */ if( genericnames ) { assert(varnames != NULL); assert(fixedvarnames != NULL); assert(consnames != NULL); for( i = 0; i < nvars; ++i ) resetVarname(vars[i], varnames[i]); for( i = 0; i < nfixedvars; ++i ) resetVarname(fixedvars[i], fixedvarnames[i]); for( i = 0; i < nconss; ++i ) { cons = conss[i]; /* get pointer to temporary generic name and free the memory */ consname = SCIPconsGetName(cons); BMSfreeMemory(&consname); /* reset name */ SCIPconsSetNamePointer(cons, consnames[i]); } /* free memory */ BMSfreeMemoryArray(&varnames); BMSfreeMemoryArray(&fixedvarnames); BMSfreeMemoryArray(&consnames); } if( prob->transformed ) { /* free memory */ BMSfreeMemoryArray(&conss); } } else { *result = SCIP_DIDNOTRUN; retcode = SCIP_OKAY; } /* check for reader errors */ if( retcode == SCIP_WRITEERROR ) return retcode; SCIP_CALL( retcode ); return SCIP_OKAY; }
/** creates a presolver */ SCIP_RETCODE SCIPpresolCreate( SCIP_PRESOL** presol, /**< pointer to store presolver */ SCIP_SET* set, /**< global SCIP settings */ SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ const char* name, /**< name of presolver */ const char* desc, /**< description of presolver */ int priority, /**< priority of the presolver (>= 0: before, < 0: after constraint handlers) */ int maxrounds, /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */ SCIP_Bool delay, /**< should presolver be delayed, if other presolvers found reductions? */ SCIP_DECL_PRESOLCOPY ((*presolcopy)), /**< copy method of presolver or NULL if you don't want to copy your plugin into sub-SCIPs */ SCIP_DECL_PRESOLFREE ((*presolfree)), /**< destructor of presolver to free user data (called when SCIP is exiting) */ SCIP_DECL_PRESOLINIT ((*presolinit)), /**< initialization method of presolver (called after problem was transformed) */ SCIP_DECL_PRESOLEXIT ((*presolexit)), /**< deinitialization method of presolver (called before transformed problem is freed) */ SCIP_DECL_PRESOLINITPRE((*presolinitpre)),/**< presolving initialization method of presolver (called when presolving is about to begin) */ SCIP_DECL_PRESOLEXITPRE((*presolexitpre)),/**< presolving deinitialization method of presolver (called after presolving has been finished) */ SCIP_DECL_PRESOLEXEC ((*presolexec)), /**< execution method of presolver */ SCIP_PRESOLDATA* presoldata /**< presolver data */ ) { char paramname[SCIP_MAXSTRLEN]; char paramdesc[SCIP_MAXSTRLEN]; assert(presol != NULL); assert(name != NULL); assert(desc != NULL); SCIP_ALLOC( BMSallocMemory(presol) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*presol)->name, name, strlen(name)+1) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*presol)->desc, desc, strlen(desc)+1) ); (*presol)->presolcopy = presolcopy; (*presol)->presolfree = presolfree; (*presol)->presolinit = presolinit; (*presol)->presolexit = presolexit; (*presol)->presolinitpre = presolinitpre; (*presol)->presolexitpre = presolexitpre; (*presol)->presolexec = presolexec; (*presol)->presoldata = presoldata; SCIP_CALL( SCIPclockCreate(&(*presol)->setuptime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*presol)->presolclock, SCIP_CLOCKTYPE_DEFAULT) ); (*presol)->wasdelayed = FALSE; (*presol)->initialized = FALSE; /* add parameters */ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "presolving/%s/priority", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of presolver <%s>", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*presol)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4, paramChgdPresolPriority, (SCIP_PARAMDATA*)(*presol)) ); /*lint !e740*/ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "presolving/%s/maxrounds", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, "maximal number of presolving rounds the presolver participates in (-1: no limit)", &(*presol)->maxrounds, FALSE, maxrounds, -1, INT_MAX, NULL, NULL) ); /*lint !e740*/ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "presolving/%s/delay", name); SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname, "should presolver be delayed, if other presolvers found reductions?", &(*presol)->delay, TRUE, delay, NULL, NULL) ); /*lint !e740*/ 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; }
/** create a set of diving heuristic settings */ SCIP_RETCODE SCIPdivesetCreate( SCIP_DIVESET** diveset, /**< pointer to the freshly created diveset */ SCIP_HEUR* heur, /**< the heuristic to which this dive setting belongs */ const char* name, /**< name for the diveset, or NULL if the name of the heuristic should be used */ SCIP_SET* set, /**< global SCIP settings */ SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ SCIP_Real minreldepth, /**< minimal relative depth to start diving */ SCIP_Real maxreldepth, /**< maximal relative depth to start diving */ SCIP_Real maxlpiterquot, /**< maximal fraction of diving LP iterations compared to node LP iterations */ SCIP_Real maxdiveubquot, /**< maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound) * where diving is performed (0.0: no limit) */ SCIP_Real maxdiveavgquot, /**< maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound) * where diving is performed (0.0: no limit) */ SCIP_Real maxdiveubquotnosol, /**< maximal UBQUOT when no solution was found yet (0.0: no limit) */ SCIP_Real maxdiveavgquotnosol,/**< maximal AVGQUOT when no solution was found yet (0.0: no limit) */ SCIP_Real lpresolvedomchgquot,/**< percentage of immediate domain changes during probing to trigger LP resolve */ int lpsolvefreq, /**< LP solve frequency for (0: only if enough domain reductions are found by propagation)*/ int maxlpiterofs, /**< additional number of allowed LP iterations */ SCIP_Bool backtrack, /**< use one level of backtracking if infeasibility is encountered? */ SCIP_Bool onlylpbranchcands, /**< should only LP branching candidates be considered instead of the slower but * more general constraint handler diving variable selection? */ SCIP_DIVETYPE divetypemask, /**< bit mask that represents the supported dive types by this dive set */ SCIP_DECL_DIVESETGETSCORE((*divesetgetscore)) /**< method for candidate score and rounding direction */ ) { char paramname[SCIP_MAXSTRLEN]; const char* divesetname; assert(diveset != NULL); assert(set != NULL); assert(divesetgetscore != NULL); assert(heur != NULL); SCIP_ALLOC( BMSallocMemory(diveset) ); /* for convenience, the name gets inferred from the heuristic to which the diveset is added if no name is provided */ divesetname = (name == NULL ? SCIPheurGetName(heur) : name); SCIP_ALLOC( BMSduplicateMemoryArray(&(*diveset)->name, divesetname, strlen(divesetname)+1) ); (*diveset)->heur = NULL; /* copy callbacks */ (*diveset)->divesetgetscore = divesetgetscore; SCIP_CALL( heurAddDiveset(heur, *diveset) ); (*diveset)->sol = NULL; (*diveset)->divetypemask = divetypemask; /* add collection of diving heuristic specific parameters */ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/minreldepth", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "minimal relative depth to start diving", &(*diveset)->minreldepth, TRUE, minreldepth, 0.0, 1.0, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxreldepth", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "maximal relative depth to start diving", &(*diveset)->maxreldepth, TRUE, maxreldepth, 0.0, 1.0, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxlpiterquot", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "maximal fraction of diving LP iterations compared to node LP iterations", &(*diveset)->maxlpiterquot, FALSE, maxlpiterquot, 0.0, SCIP_REAL_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxlpiterofs", (*diveset)->name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, "additional number of allowed LP iterations", &(*diveset)->maxlpiterofs, FALSE, maxlpiterofs, 0, INT_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveubquot", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound) where diving is performed (0.0: no limit)", &(*diveset)->maxdiveubquot, TRUE, maxdiveubquot, 0.0, 1.0, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveavgquot", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound) where diving is performed (0.0: no limit)", &(*diveset)->maxdiveavgquot, TRUE, maxdiveavgquot, 0.0, SCIP_REAL_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveubquotnosol", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "maximal UBQUOT when no solution was found yet (0.0: no limit)", &(*diveset)->maxdiveubquotnosol, TRUE, maxdiveubquotnosol, 0.0, 1.0, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveavgquotnosol", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "maximal AVGQUOT when no solution was found yet (0.0: no limit)", &(*diveset)->maxdiveavgquotnosol, TRUE, maxdiveavgquotnosol, 0.0, SCIP_REAL_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/backtrack", (*diveset)->name); SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname, "use one level of backtracking if infeasibility is encountered?", &(*diveset)->backtrack, FALSE, backtrack, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/lpresolvedomchgquot", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "percentage of immediate domain changes during probing to trigger LP resolve", &(*diveset)->lpresolvedomchgquot, FALSE, lpresolvedomchgquot, 0.0, SCIP_REAL_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/lpsolvefreq", (*diveset)->name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, "LP solve frequency for diving heuristics (0: only after enough domain changes have been found)", &(*diveset)->lpsolvefreq, FALSE, lpsolvefreq, 0, INT_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/onlylpbranchcands", (*diveset)->name); SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname, "should only LP branching candidates be considered instead of the slower but " "more general constraint handler diving variable selection?", &(*diveset)->onlylpbranchcands, FALSE, onlylpbranchcands, NULL, NULL) ); SCIPdivesetReset(*diveset); return SCIP_OKAY; }
/** creates a presolver */ SCIP_RETCODE SCIPpresolCreate( SCIP_PRESOL** presol, /**< pointer to store presolver */ SCIP_SET* set, /**< global SCIP settings */ SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ const char* name, /**< name of presolver */ const char* desc, /**< description of presolver */ int priority, /**< priority of the presolver (>= 0: before, < 0: after constraint handlers) */ int maxrounds, /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */ SCIP_PRESOLTIMING timing, /**< timing mask of the presolver */ SCIP_DECL_PRESOLCOPY ((*presolcopy)), /**< copy method of presolver or NULL if you don't want to copy your plugin into sub-SCIPs */ SCIP_DECL_PRESOLFREE ((*presolfree)), /**< destructor of presolver to free user data (called when SCIP is exiting) */ SCIP_DECL_PRESOLINIT ((*presolinit)), /**< initialization method of presolver (called after problem was transformed) */ SCIP_DECL_PRESOLEXIT ((*presolexit)), /**< deinitialization method of presolver (called before transformed problem is freed) */ SCIP_DECL_PRESOLINITPRE((*presolinitpre)),/**< presolving initialization method of presolver (called when presolving is about to begin) */ SCIP_DECL_PRESOLEXITPRE((*presolexitpre)),/**< presolving deinitialization method of presolver (called after presolving has been finished) */ SCIP_DECL_PRESOLEXEC ((*presolexec)), /**< execution method of presolver */ SCIP_PRESOLDATA* presoldata /**< presolver data */ ) { char paramname[SCIP_MAXSTRLEN]; char paramdesc[SCIP_MAXSTRLEN]; assert(presol != NULL); assert(name != NULL); assert(desc != NULL); /* the interface change from delay flags to timings cannot be recognized at compile time: Exit with an appropriate * error message */ if( timing < SCIP_PRESOLTIMING_FAST || timing > SCIP_PRESOLTIMING_ALWAYS ) { SCIPmessagePrintError("ERROR: 'PRESOLDELAY'-flag no longer available since SCIP 3.2, use an appropriate " "'SCIP_PRESOLTIMING' for <%s> presolver instead.\n", name); return SCIP_PARAMETERWRONGVAL; } SCIP_ALLOC( BMSallocMemory(presol) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*presol)->name, name, strlen(name)+1) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*presol)->desc, desc, strlen(desc)+1) ); (*presol)->presolcopy = presolcopy; (*presol)->presolfree = presolfree; (*presol)->presolinit = presolinit; (*presol)->presolexit = presolexit; (*presol)->presolinitpre = presolinitpre; (*presol)->presolexitpre = presolexitpre; (*presol)->presolexec = presolexec; (*presol)->presoldata = presoldata; SCIP_CALL( SCIPclockCreate(&(*presol)->setuptime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*presol)->presolclock, SCIP_CLOCKTYPE_DEFAULT) ); (*presol)->initialized = FALSE; /* add parameters */ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "presolving/%s/priority", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of presolver <%s>", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*presol)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4, paramChgdPresolPriority, (SCIP_PARAMDATA*)(*presol)) ); /*lint !e740*/ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "presolving/%s/maxrounds", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, "maximal number of presolving rounds the presolver participates in (-1: no limit)", &(*presol)->maxrounds, FALSE, maxrounds, -1, INT_MAX, NULL, NULL) ); /*lint !e740*/ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "presolving/%s/timing", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "timing mask of presolver <%s> (%u:FAST, %u:MEDIUM, %u:EXHAUSTIVE)", name, SCIP_PRESOLTIMING_FAST, SCIP_PRESOLTIMING_MEDIUM, SCIP_PRESOLTIMING_EXHAUSTIVE); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, (int*)&(*presol)->timing, TRUE, (int)timing, (int) SCIP_PRESOLTIMING_FAST, (int) SCIP_PRESOLTIMING_ALWAYS, NULL, NULL) ); /*lint !e740*/ return SCIP_OKAY; }
/** 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; }