/** creates a new solution for the original problem by copying the solution of the subproblem */ static SCIP_RETCODE createNewSol( SCIP* scip, /**< original SCIP data structure */ SCIP* subscip, /**< SCIP structure of the subproblem */ SCIP_VAR** subvars, /**< the variables of the subproblem */ SCIP_HEUR* heur, /**< crossover heuristic structure */ SCIP_SOL* subsol, /**< solution of the subproblem */ int* solindex, /**< index of the solution */ SCIP_Bool* success /**< used to store whether new solution was found or not */ ) { SCIP_VAR** vars; /* the original problem's variables */ int nvars; SCIP_SOL* newsol; /* solution to be created for the original problem */ SCIP_Real* subsolvals; /* solution values of the subproblem */ assert(scip != NULL); assert(subscip != NULL); assert(subvars != NULL); assert(subsol != NULL); /* get variables' data */ SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) ); /* sub-SCIP may have more variables than the number of active (transformed) variables in the main SCIP * since constraint copying may have required the copy of variables that are fixed in the main SCIP */ assert(nvars <= SCIPgetNOrigVars(subscip)); SCIP_CALL( SCIPallocBufferArray(scip, &subsolvals, nvars) ); /* copy the solution */ SCIP_CALL( SCIPgetSolVals(subscip, subsol, nvars, subvars, subsolvals) ); /* create new solution for the original problem */ SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) ); SCIP_CALL( SCIPsetSolVals(scip, newsol, nvars, vars, subsolvals) ); *solindex = SCIPsolGetIndex(newsol); /* try to add new solution to scip and free it immediately */ SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, success) ); SCIPfreeBufferArray(scip, &subsolvals); return SCIP_OKAY; }
/** creates a new solution for the original problem by copying the solution of the subproblem */ static SCIP_RETCODE createNewSol( SCIP* scip, /**< SCIP data structure of the original problem */ SCIP* subscip, /**< SCIP data structure of the subproblem */ SCIP_VAR** subvars, /**< the variables of the subproblem */ SCIP_HEUR* heur, /**< the Localbranching heuristic */ SCIP_SOL* subsol, /**< solution of the subproblem */ SCIP_Bool* success /**< pointer to store, whether new solution was found */ ) { SCIP_VAR** vars; int nvars; SCIP_SOL* newsol; SCIP_Real* subsolvals; assert( scip != NULL ); assert( subscip != NULL ); assert( subvars != NULL ); assert( subsol != NULL ); /* copy the solution */ SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) ); /* sub-SCIP may have more variables than the number of active (transformed) variables in the main SCIP * since constraint copying may have required the copy of variables that are fixed in the main SCIP */ assert(nvars <= SCIPgetNOrigVars(subscip)); SCIP_CALL( SCIPallocBufferArray(scip, &subsolvals, nvars) ); /* copy the solution */ SCIP_CALL( SCIPgetSolVals(subscip, subsol, nvars, subvars, subsolvals) ); /* create new solution for the original problem */ SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) ); SCIP_CALL( SCIPsetSolVals(scip, newsol, nvars, vars, subsolvals) ); SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, success) ); SCIPfreeBufferArray(scip, &subsolvals); return SCIP_OKAY; }
/** creates the objective value inequality and the objective value variable, if not yet existing */ static SCIP_RETCODE createObjRow( SCIP* scip, /**< SCIP data structure */ SCIP_SEPA* sepa, /**< separator */ SCIP_SEPADATA* sepadata /**< separator data */ ) { assert(sepadata != NULL); if( sepadata->objrow == NULL ) { SCIP_VAR** vars; SCIP_Real obj; SCIP_Real intobjval; int nvars; int v; SCIP_Bool attendobjvarbound; attendobjvarbound = FALSE; /* create and add objective value variable */ if( sepadata->objvar == NULL ) { SCIP_CALL( SCIPcreateVar(scip, &sepadata->objvar, "objvar", -SCIPinfinity(scip), SCIPinfinity(scip), 0.0, SCIP_VARTYPE_IMPLINT, FALSE, TRUE, NULL, NULL, NULL, NULL, NULL) ); SCIP_CALL( SCIPaddVar(scip, sepadata->objvar) ); SCIP_CALL( SCIPaddVarLocks(scip, sepadata->objvar, +1, +1) ); } else attendobjvarbound = TRUE; /* get problem variables */ vars = SCIPgetOrigVars(scip); nvars = SCIPgetNOrigVars(scip); /* create objective value inequality */ if( SCIPgetObjsense(scip) == SCIP_OBJSENSE_MINIMIZE ) { if( attendobjvarbound ) intobjval = SCIPceil(scip, SCIPgetDualbound(scip)) - SCIPvarGetLbGlobal(sepadata->objvar); else intobjval = SCIPceil(scip, SCIPgetDualbound(scip)); SCIP_CALL( SCIPcreateEmptyRowSepa(scip, &sepadata->objrow, sepa, "objrow", intobjval, SCIPinfinity(scip), FALSE, !SCIPallVarsInProb(scip), TRUE) ); sepadata->setoff = intobjval; } else { if( attendobjvarbound ) intobjval = SCIPceil(scip, SCIPgetDualbound(scip)) - SCIPvarGetUbGlobal(sepadata->objvar); else intobjval = SCIPfloor(scip, SCIPgetDualbound(scip)); SCIP_CALL( SCIPcreateEmptyRowSepa(scip, &sepadata->objrow, sepa, "objrow", -SCIPinfinity(scip), intobjval, FALSE, !SCIPallVarsInProb(scip), TRUE) ); sepadata->setoff = intobjval; } SCIP_CALL( SCIPcacheRowExtensions(scip, sepadata->objrow) ); for( v = 0; v < nvars; ++v ) { obj = SCIPvarGetObj(vars[v]); if( !SCIPisZero(scip, obj) ) { SCIP_CALL( SCIPaddVarToRow(scip, sepadata->objrow, vars[v], obj) ); } } SCIP_CALL( SCIPaddVarToRow(scip, sepadata->objrow, sepadata->objvar, -1.0) ); SCIP_CALL( SCIPflushRowExtensions(scip, sepadata->objrow) ); SCIPdebugMessage("created objective value row: "); SCIPdebug( SCIP_CALL( SCIPprintRow(scip, sepadata->objrow, NULL) ) ); } return SCIP_OKAY; }
/** execution method of event handler */ static SCIP_DECL_EVENTEXEC(eventExecBoundwriting) { /*lint --e{715}*/ SCIP_EVENTHDLRDATA* eventhdlrdata; assert(scip != NULL); assert(eventhdlr != NULL); assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0); assert(event != NULL); assert(((SCIPeventGetType(event) & SCIP_EVENTTYPE_NODESOLVED) == SCIP_EVENTTYPE_NODEFEASIBLE) || ((SCIPeventGetType(event) & SCIP_EVENTTYPE_NODESOLVED) == SCIP_EVENTTYPE_NODEINFEASIBLE) || ((SCIPeventGetType(event) & SCIP_EVENTTYPE_NODESOLVED) == SCIP_EVENTTYPE_NODEBRANCHED)); SCIPdebugMessage("exec method of event handler for writing primal- and dualbounds\n"); eventhdlrdata = SCIPeventhdlrGetData(eventhdlr); assert(eventhdlrdata != NULL); #ifdef ONEFILE /* check if we need to open the file */ if( strlen(eventhdlrdata->filename) > 0 && !eventhdlrdata->isopen ) { assert(eventhdlrdata->file == NULL); assert(eventhdlrdata->oldfilename[0] == '\0'); eventhdlrdata->file = fopen(eventhdlrdata->filename, "w"); (void)strncpy(eventhdlrdata->oldfilename, eventhdlrdata->filename, SCIP_MAXSTRLEN); if( eventhdlrdata->file == NULL ) { SCIPerrorMessage("cannot create file <%s> for writing\n", eventhdlrdata->filename); SCIPprintSysError(eventhdlrdata->filename); return SCIP_FILECREATEERROR; } eventhdlrdata->isopen = TRUE; #ifdef LONGSTATS SCIPinfoMessage(scip, eventhdlrdata->file, "Problem: %s (%d Original Constraints, %d Original Variables)\n", SCIPgetProbName(scip), SCIPgetNOrigConss(scip), SCIPgetNOrigVars(scip) ); SCIPinfoMessage(scip, eventhdlrdata->file, "\t (%d Presolved Constraints, %d Presolved Variables, (%d binary, %d integer, %d implicit integer, %d continuous))\n", SCIPgetNConss(scip), SCIPgetNVars(scip), SCIPgetNBinVars(scip), SCIPgetNIntVars(scip), SCIPgetNImplVars(scip), SCIPgetNContVars(scip)); SCIPinfoMessage(scip, eventhdlrdata->file, "\n"); #endif } #endif /* call writing only at right moment */ if( eventhdlrdata->freq == 0 || (SCIPgetNNodes(scip) % eventhdlrdata->freq) != 0 ) return SCIP_OKAY; #ifndef ONEFILE if( strlen(eventhdlrdata->filename) > 0 ) { char name[SCIP_MAXSTRLEN]; char number[SCIP_MAXSTRLEN]; char* pch; int n; assert(eventhdlrdata->file == NULL); assert(!eventhdlrdata->isopen); if( eventhdlrdata->oldfilename[0] == '\0' ) (void)strncpy(eventhdlrdata->oldfilename, eventhdlrdata->filename, SCIP_MAXSTRLEN); /* find last '.' to append filenumber */ pch=strrchr(eventhdlrdata->filename,'.'); assert(eventhdlrdata->filenumber > 0); n=sprintf(number, "%"SCIP_LONGINT_FORMAT"", eventhdlrdata->filenumber * eventhdlrdata->freq); assert(n > 0); assert(n < SCIP_MAXSTRLEN); /* if no point is found, extend directly */ if( pch == NULL ) { (void)strncpy(name, eventhdlrdata->filename, (unsigned int)(SCIP_MAXSTRLEN - n)); strncat(name, number, (unsigned int)n); } else { int len; if( (pch-(eventhdlrdata->filename)) > (SCIP_MAXSTRLEN - n) ) /*lint !e776*/ len = SCIP_MAXSTRLEN - n; else len = (int) (pch-(eventhdlrdata->filename)); (void)strncpy(name, eventhdlrdata->filename, (unsigned int)len); name[len] = '\0'; strncat(name, number, (unsigned int)n); assert(len+n < SCIP_MAXSTRLEN); name[len+n] = '\0'; if( len + n + strlen(&(eventhdlrdata->filename[len])) < SCIP_MAXSTRLEN ) /*lint !e776*/ { strncat(name, &(eventhdlrdata->filename[len]), strlen(&(eventhdlrdata->filename[len]))); name[strlen(eventhdlrdata->filename)+n] = '\0'; } } eventhdlrdata->file = fopen(name, "w"); if( eventhdlrdata->file == NULL ) { SCIPerrorMessage("cannot create file <%s> for writing\n", eventhdlrdata->filename); SCIPprintSysError(eventhdlrdata->filename); return SCIP_FILECREATEERROR; } eventhdlrdata->isopen = TRUE; #ifdef LONGSTATS SCIPinfoMessage(scip, eventhdlrdata->file, "Problem: %s (%d Original Constraints, %d Original Variables)\n", SCIPgetProbName(scip), SCIPgetNOrigConss(scip), SCIPgetNOrigVars(scip) ); SCIPinfoMessage(scip, eventhdlrdata->file, "\t (%d Active Constraints, %d Active Variables, (%d binary, %d integer, %d implicit integer, %d continuous))\n", SCIPgetNConss(scip), SCIPgetNVars(scip), SCIPgetNBinVars(scip), SCIPgetNIntVars(scip), SCIPgetNImplVars(scip), SCIPgetNContVars(scip)); SCIPinfoMessage(scip, eventhdlrdata->file, "\n"); #endif } #endif #ifndef NDEBUG /* check the filename did not change during the solving */ if( strlen(eventhdlrdata->filename) > 0 && eventhdlrdata->isopen ) { char tmp[SCIP_MAXSTRLEN]; (void)strncpy(tmp, eventhdlrdata->filename, SCIP_MAXSTRLEN); /* the name should stay the same */ assert(strcmp(tmp, eventhdlrdata->oldfilename) == 0); } #endif #ifdef FOCUSNODE /* call writing method */ SCIP_CALL( writeBoundsFocusNode(scip, eventhdlrdata) ); #else /* call writing method */ SCIP_CALL( writeBounds(scip, eventhdlrdata->file, eventhdlrdata->writesubmipdualbound) ); #endif #ifndef ONEFILE if( strlen(eventhdlrdata->filename) > 0 ) { assert(eventhdlrdata->isopen); (void) fclose(eventhdlrdata->file); eventhdlrdata->isopen = FALSE; eventhdlrdata->file = NULL; ++(eventhdlrdata->filenumber); } #endif return SCIP_OKAY; }
/** propagator to force finding the debugging solution */ static SCIP_DECL_PROPEXEC(propExecDebug) { /*lint --e{715}*/ SCIP_VAR** vars; int nvars; int i; assert(scip != NULL); assert(result != NULL); *result = SCIP_DIDNOTFIND; /* check if we are in the original problem and not in a sub MIP */ if( !isSolutionInMip(scip->set) ) return SCIP_OKAY; if( SCIPgetStage(scip) != SCIP_STAGE_SOLVING ) return SCIP_OKAY; /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ if( debugSolIsAchieved(scip->set) ) return SCIP_OKAY; #if 1 /* solve at least one LP */ if( SCIPgetNLPIterations(scip) == 0 ) return SCIP_OKAY; #endif vars = SCIPgetOrigVars(scip); nvars = SCIPgetNOrigVars(scip); for( i = 0; i < nvars; ++i ) { SCIP_Real solval; SCIP_Real lb; SCIP_Real ub; SCIP_Bool infeasible; SCIP_Bool fixed; SCIP_CALL( getSolutionValue(scip->set, vars[i], &solval) ); if( solval == SCIP_UNKNOWN ) /*lint !e777*/ { SCIPerrorMessage("original variable without debugging solution value\n"); SCIPABORT(); } lb = SCIPvarGetLbGlobal(vars[i]); ub = SCIPvarGetUbGlobal(vars[i]); if( SCIPisLT(scip, solval, lb) || SCIPisGT(scip, solval, ub) ) { SCIPerrorMessage("solution value %.15g of <%s> outside bounds loc=[%.15g,%.15g], glb=[%.15g,%.15g]\n", solval, SCIPvarGetName(vars[i]), lb, ub, SCIPvarGetLbGlobal(vars[i]), SCIPvarGetUbGlobal(vars[i])); SCIPABORT(); } SCIP_CALL( SCIPfixVar(scip, vars[i], solval, &infeasible, &fixed) ); if( infeasible ) *result = SCIP_CUTOFF; else if( fixed ) *result = SCIP_REDUCEDDOM; } return SCIP_OKAY; }