/** reads the masterconss section */ static SCIP_RETCODE readMasterconss( SCIP* scip, /**< SCIP data structure */ BLKINPUT* blkinput, /**< BLK reading data */ SCIP_READERDATA* readerdata /**< reader data */ ) { assert(blkinput != NULL); while( getNextToken(blkinput) ) { SCIP_CONS* cons; /* check if we reached a new section */ if( isNewSection(scip, blkinput) ) return SCIP_OKAY; /* the token must be the name of an existing constraint */ cons = SCIPfindCons(scip, blkinput->token); if( cons == NULL ) { syntaxError(scip, blkinput, "unknown constraint in masterconss section"); return SCIP_OKAY; } else { assert(SCIPhashmapGetImage(readerdata->constoblock, cons) == (void*)(size_t)NOVALUE); SCIP_CALL( SCIPhashmapSetImage(readerdata->constoblock, cons, (void*)(size_t) (blkinput->nblocks +1)) ); } } return SCIP_OKAY; }
/** fills the whole Decomp struct after the dec file has been read */ static SCIP_RETCODE fillDecompStruct( SCIP* scip, /**< SCIP data structure */ DECINPUT* decinput, /**< DEC reading data */ DEC_DECOMP* decomp, /**< DEC_DECOMP structure to fill */ SCIP_READERDATA* readerdata /**< reader data*/ ) { SCIP_HASHMAP* constoblock; SCIP_CONS** allcons; int i; int j; int nblockconss; int nconss; int nblocks; SCIP_Bool valid; assert(scip != NULL); assert(decinput != NULL); assert(decomp != NULL); assert(readerdata != NULL); valid = FALSE; allcons = SCIPgetConss(scip); nconss = SCIPgetNConss(scip); nblocks = decinput->nblocks; DECdecompSetPresolved(decomp, decinput->presolved); DECdecompSetNBlocks(decomp, nblocks); DECdecompSetDetector(decomp, NULL); DECdecompSetType(decomp, DEC_DECTYPE_ARROWHEAD, &valid); assert(valid); /* hashmaps */ SCIP_CALL( SCIPhashmapCreate(&constoblock, SCIPblkmem(scip), nconss) ); for( i = 0; i < nconss; i ++ ) { SCIP_CALL( SCIPhashmapInsert(constoblock, allcons[i], (void*) (size_t) (nblocks+1)) ); } for( i = 0; i < nblocks; i ++ ) { nblockconss = readerdata->nblockconss[i]; for( j = 0; j < nblockconss; j ++ ) { /* hashmap */ SCIPdebugMessage("cons %s is in block %d\n", SCIPconsGetName(readerdata->blockconss[i][j]), i); SCIP_CALL( SCIPhashmapSetImage(constoblock, readerdata->blockconss[i][j], (void*) (size_t) (i+1)) ); } } SCIP_CALL( DECfilloutDecdecompFromConstoblock(scip, decomp, constoblock, nblocks, SCIPgetVars(scip), SCIPgetNVars(scip), SCIPgetConss(scip), SCIPgetNConss(scip), FALSE) ); return SCIP_OKAY; }
/** returns whether the solution is contained in node's subproblem */ static SCIP_RETCODE isSolutionInNode( BMS_BLKMEM* blkmem, /**< block memory */ SCIP_SET* set, /**< global SCIP settings */ SCIP_NODE* node, /**< local node where this bound change was applied */ SCIP_Bool* solcontained /**< pointer to store whether the solution is contained in node's subproblem */ ) { SCIP_Bool* boolptr; assert(set != NULL); assert(blkmem != NULL); assert(node != NULL); assert(solcontained != NULL); /* check if we are in the original problem and not in a sub MIP */ if( !isSolutionInMip(set) ) { *solcontained = FALSE; return SCIP_OKAY; } /* generate the hashmap */ if( solinnode == NULL ) { SCIP_CALL( SCIPhashmapCreate(&solinnode, blkmem, SCIPcalcHashtableSize(SCIP_HASHSIZE_DEBUG)) ); } /* check, whether we know already whether the solution is contained in the given node */ boolptr = (SCIP_Bool*)SCIPhashmapGetImage(solinnode, (void*)node); if( boolptr != NULL ) { if( boolptr != &falseptr && boolptr != &trueptr ) { SCIPerrorMessage("wrong value in node hashmap\n"); SCIPABORT(); } *solcontained = *boolptr; return SCIP_OKAY; } /* if the solution is not contained in the parent of the node, it cannot be contained in the current node */ *solcontained = TRUE; if( node->parent != NULL ) { SCIP_CALL( isSolutionInNode(blkmem, set, node->parent, solcontained) ); } if( *solcontained ) { /* check whether the bound changes at the current node remove the debugging solution from the subproblem */ if( node->domchg != NULL ) { SCIP_DOMCHGBOUND* domchgbound; SCIP_BOUNDCHG* boundchgs; int i; domchgbound = &node->domchg->domchgbound; boundchgs = domchgbound->boundchgs; for( i = 0; i < (int)domchgbound->nboundchgs && *solcontained; ++i ) { SCIP_Real varsol; if( SCIPboundchgIsRedundant(&boundchgs[i]) ) continue; /* get solution value of variable */ SCIP_CALL( getSolutionValue(set, boundchgs[i].var, &varsol) ); if( varsol != SCIP_UNKNOWN ) /*lint !e777*/ { /* compare the bound change with the solution value */ if( SCIPboundchgGetBoundtype(&boundchgs[i]) == SCIP_BOUNDTYPE_LOWER ) *solcontained = SCIPsetIsFeasGE(set, varsol, boundchgs[i].newbound); else *solcontained = SCIPsetIsFeasLE(set, varsol, boundchgs[i].newbound); if( !(*solcontained) && SCIPboundchgGetBoundchgtype(&boundchgs[i]) != SCIP_BOUNDCHGTYPE_BRANCHING ) { SCIPerrorMessage("debugging solution was cut off in local node %p at depth %d by inference <%s>[%.15g] %s %.15g\n", node, SCIPnodeGetDepth(node), SCIPvarGetName(boundchgs[i].var), varsol, SCIPboundchgGetBoundtype(&boundchgs[i]) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", boundchgs[i].newbound); SCIPABORT(); } } else if( SCIPboundchgGetBoundchgtype(&boundchgs[i]) == SCIP_BOUNDCHGTYPE_BRANCHING ) { /* we branched on a variable were we don't know the solution: no debugging can be applied in this subtree */ *solcontained = FALSE; } } } } /* remember the status of the current node */ SCIP_CALL( SCIPhashmapSetImage(solinnode, (void*)node, *solcontained ? (void*)(&trueptr) : (void*)(&falseptr)) ); return SCIP_OKAY; }
/** reads the blocks section */ static SCIP_RETCODE readBlock( SCIP* scip, /**< SCIP data structure */ DECINPUT* decinput, /**< DEC reading data */ SCIP_READERDATA* readerdata /**< reader data */ ) { int oldblock; int varidx; int consindex; int i; int blockid; int nvars; SCIP_CONS* cons; SCIP_VAR** vars; SCIP_Bool conshasvar; assert(decinput != NULL); assert(readerdata != NULL); while( getNextToken(decinput) ) { /* check if we reached a new section */ if( isNewSection(scip, decinput) ) break; /* the token must be the name of an existing cons */ cons = SCIPfindCons(scip, decinput->token); if( cons == NULL ) { syntaxError(scip, decinput, "unknown constraint in block section"); break; } conshasvar = FALSE; /* get all vars for the specific constraint */ nvars = SCIPgetNVarsXXX(scip, cons); vars = NULL; if( nvars > 0 ) { SCIP_CALL( SCIPallocMemoryArray(scip, &vars, nvars) ); SCIP_CALL( SCIPgetVarsXXX(scip, cons, vars, nvars) ); } blockid = decinput->blocknr; for( i = 0; i < nvars; i ++ ) { SCIP_VAR* var; assert(vars != NULL); /* for flexelint */ if( decinput->presolved ) { var = SCIPvarGetProbvar(vars[i]); if( !SCIPisVarRelevant(var) ) continue; } else var = vars[i]; conshasvar = TRUE; /* store for each var whether it is in none, one or more blocks */ varidx = SCIPvarGetProbindex(var); assert(varidx >= 0 && varidx < SCIPgetNVars(scip)); oldblock = readerdata->varstoblock[varidx]; assert(oldblock == NOVALUE || oldblock == LINKINGVALUE || (oldblock >= 0 && oldblock < decinput->nblocks)); /* variable was assigned to no block before, just assign it to the new block */ if( oldblock == NOVALUE ) { SCIPdebugMessage("\tVar %s temporary in block %d.\n", SCIPvarGetName(vars[i]), blockid); readerdata->varstoblock[varidx] = blockid; ++(readerdata->nblockvars[blockid]); } /* variable was assigned to another (non-linking) block before, so it becomes a linking variable, now */ else if( (oldblock != LINKINGVALUE) && oldblock != blockid ) { SCIPdebugMessage("\tVar %s is linking (old %d != %d new).\n", SCIPvarGetName(vars[i]), oldblock, blockid); assert(oldblock != blockid); readerdata->varstoblock[varidx] = LINKINGVALUE; /* decrease the value again if it is a linking var */ --(readerdata->nblockvars[oldblock]); ++(readerdata->nlinkingvars); } } SCIPfreeMemoryArrayNull(scip, &vars); if( !conshasvar ) { assert(!SCIPhashmapExists(readerdata->constoblock, cons)); SCIPwarningMessage(scip, "Cons <%s> has been deleted by presolving, skipping.\n", SCIPconsGetName(cons)); continue; } /* * saving block <-> constraint */ /** @todo check if linking constraints are not in the subscipcons */ consindex = readerdata->nblockconss[blockid]; readerdata->blockconss[blockid][consindex] = cons; ++(readerdata->nblockconss[blockid]); assert(SCIPhashmapGetImage(readerdata->constoblock, cons) == (void*)(size_t) LINKINGVALUE); SCIPdebugMessage("cons %s is in block %d\n", SCIPconsGetName(cons), blockid); SCIP_CALL( SCIPhashmapSetImage(readerdata->constoblock, cons, (void*) ((size_t) blockid)) ); --(readerdata->nlinkingconss); } return SCIP_OKAY; }