/** 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; }
/** 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 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; }
/** create new attribute */ XML_ATTR* xml_new_attr( const char* name, const char* value ) { XML_ATTR* a = NULL; assert(name != NULL); assert(value != NULL); if ( BMSallocMemory(&a) != NULL ) { BMSclearMemory(a); BMSduplicateMemoryArray(&a->name, name, strlen(name)+1); BMSduplicateMemoryArray(&a->value, value, strlen(value)+1); } return a; }
/** 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; }
/** create new node */ XML_NODE* xml_new_node( const char* name, int lineno ) { XML_NODE* n = NULL; assert(name != NULL); if ( BMSallocMemory(&n) != NULL ) { BMSclearMemory(n); BMSduplicateMemoryArray(&n->name, name, strlen(name)+1); n->lineno = lineno; } return n; }
/** 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; }
/** 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; }
/** 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; }
/* 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); } } }
/** 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; }
/** Parse file */ XML_NODE* xml_process( const char* filename /**< XML file name */ ) { PPOS ppos; XML_NODE* node = NULL; XML_ATTR* attr; int result = FALSE; char* myfilename; ALLOC_FALSE( BMSduplicateMemoryArray(&myfilename, filename, strlen(filename) + 5) ); #ifdef WITH_ZLIB if (access(filename, R_OK) != 0) { strcat(myfilename, ".gz"); /* If .gz also does not work, revert to the old name * to get a better error message. */ if (access(myfilename, R_OK) != 0) strcpy(myfilename, filename); } #endif ppos.fp = FOPEN(myfilename, "r"); if ( ppos.fp == NULL ) perror(myfilename); else { ppos.filename = myfilename; ppos.buf[0] = '\0'; ppos.pos = 0; ppos.lineno = 1; ppos.nextsym = 0; ppos.lastsym = 0; ppos.state = STATE_BEFORE; ppos.top = NULL; node = xml_new_node("#ROOT", ppos.lineno); if ( node == NULL ) { xml_error(&ppos, "Can't create new node"); } else { attr = xml_new_attr("filename", myfilename); if ( attr == NULL ) xml_error(&ppos, "Can't create new attribute"); else { xml_add_attr(node, attr); /* push root node on stack and start to process */ if ( push_pstack(&ppos, node) ) { result = xml_parse(&ppos); clear_pstack(&ppos); } } } if ( ! result && (node != NULL) ) { xml_errmsg(&ppos, "Parsing error, processing stopped", TRUE, __FILE__, __LINE__); xml_free_node(node); node = NULL; } if (FCLOSE(ppos.fp)) perror(myfilename); } BMSfreeMemoryArray(&myfilename); return node; }
/** 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; }
/** 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; }
/** Handles declarations that start with a <!. * * This includes comments. Does currenlty not work very well, because of DTDs. */ static void handle_decl( PPOS* ppos ) { enum XmlSection { IS_COMMENT, IS_ATTLIST, IS_DOCTYPE, IS_ELEMENT, IS_ENTITY, IS_NOTATION, IS_CDATA }; typedef enum XmlSection XMLSECTION; static struct { const char* name; XMLSECTION what; } key[] = { { "--", IS_COMMENT }, { "ATTLIST", IS_ATTLIST }, { "DOCTYPE", IS_DOCTYPE }, { "ELEMENT", IS_ELEMENT }, { "ENTITY", IS_ENTITY }, { "NOTATION", IS_NOTATION }, { "[CDATA[", IS_CDATA } }; XML_NODE* node; char* data; int c; int k = 0; int beg = 0; int end = (sizeof(key) / sizeof(key[0])) - 1; assert(ppos != NULL); assert(ppos->state == STATE_BEFORE); do { c = getsymbol(ppos); for(; (beg <= end) && (c != key[beg].name[k]); beg++) ; for(; (end >= beg) && (c != key[end].name[k]); end--) ; k++; } while(beg < end); if (beg != end) { xml_error(ppos, "Unknown declaration"); while((c != EOF) && (c != '>')) c = getsymbol(ppos); } else { assert(beg == end); assert(beg < (int)(sizeof(key) / sizeof(*key))); switch(key[beg].what) { case IS_COMMENT : if (do_comment(ppos)) ppos->state = STATE_ERROR; break; case IS_CDATA : if ((data = do_cdata(ppos)) == NULL) ppos->state = STATE_ERROR; else { if (NULL == (node = xml_new_node("#CDATA", ppos->lineno))) { xml_error(ppos, "Can't create new node"); ppos->state = STATE_ERROR; } else { BMSduplicateMemoryArray(&node->data, data, strlen(data)+1); BMSfreeMemoryArray(&data); xml_append_child(top_pstack(ppos), node); } } break; case IS_ATTLIST : case IS_ELEMENT : case IS_NOTATION : case IS_ENTITY : case IS_DOCTYPE : break; default : abort(); } } }
/** 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; }
/** 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; }