/** output method of display column to output file stream 'file' */ static SCIP_DECL_DISPOUTPUT(SCIPdispOutputGap) { /*lint --e{715}*/ SCIP_Real gap; assert(disp != NULL); assert(strcmp(SCIPdispGetName(disp), DISP_NAME_GAP) == 0); assert(scip != NULL); gap = SCIPgetGap(scip); if( SCIPisInfinity(scip, gap) ) SCIPinfoMessage(scip, file, " Inf "); else if( gap >= 100.00 ) SCIPinfoMessage(scip, file, " Large "); else SCIPinfoMessage(scip, file, "%7.2f%%", 100.0*gap); if( SCIPgetNNodesLeft(scip) > 0 || SCIPisZero(scip, gap) ) { SCIP_CALL( SCIPsetIntParam(scip, "display/verblevel", 0) ); } return SCIP_OKAY; }
/** output method of display column to output file stream 'file' */ static SCIP_DECL_DISPOUTPUT(SCIPdispOutputNodesleft) { /*lint --e{715}*/ assert(disp != NULL); assert(strcmp(SCIPdispGetName(disp), DISP_NAME_NODESLEFT) == 0); assert(scip != NULL); SCIPdispInt(SCIPgetMessagehdlr(scip), file, SCIPgetNNodesLeft(scip), DISP_WIDT_NODESLEFT); return SCIP_OKAY; }
/** call writing method */ static SCIP_RETCODE writeBounds( SCIP* scip, /**< SCIP data structure */ FILE* file, /**< file to write to or NULL */ SCIP_Bool writesubmipdualbound/**< write dualbounds of submip roots for all open nodes */ ) { SCIP_NODE** opennodes; int nopennodes; int n; int v; assert(scip != NULL); nopennodes = -1; #ifdef LONGSTATS SCIPinfoMessage(scip, file, "Status after %"SCIP_LONGINT_FORMAT" processed nodes (%d open)\n", SCIPgetNNodes(scip), SCIPgetNNodesLeft(scip)); SCIPinfoMessage(scip, file, "Primalbound: %g\n", SCIPgetPrimalbound(scip)); SCIPinfoMessage(scip, file, "Dualbound: %g\n", SCIPgetDualbound(scip)); #else SCIPinfoMessage(scip, file, "PB %g\n", SCIPgetPrimalbound(scip)); #endif /* get all open nodes and therefor print all dualbounds */ for( v = 2; v >= 0; --v ) { SCIP_NODE* node; switch( v ) { case 2: SCIP_CALL( SCIPgetChildren(scip, &opennodes, &nopennodes) ); break; case 1: SCIP_CALL( SCIPgetSiblings(scip, &opennodes, &nopennodes) ); break; case 0: SCIP_CALL( SCIPgetLeaves(scip, &opennodes, &nopennodes) ); break; default: assert(0); break; } assert(nopennodes >= 0); /* print all node information */ for( n = nopennodes - 1; n >= 0 && !SCIPisStopped(scip); --n ) { node = opennodes[n]; if( writesubmipdualbound ) { SCIP* subscip; SCIP_Bool valid; SCIP_HASHMAP* varmap; /* mapping of SCIP variables to sub-SCIP variables */ SCIP_VAR** vars; /* original problem's variables */ int nvars; SCIP_Real submipdb; SCIP_Bool cutoff; SCIP_CALL( SCIPcreate(&subscip) ); SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) ); /* create the variable mapping hash map */ SCIP_CALL( SCIPhashmapCreate(&varmap, SCIPblkmem(subscip), SCIPcalcHashtableSize(5 * nvars)) ); submipdb = SCIP_INVALID; valid = FALSE; cutoff = FALSE; SCIP_CALL( SCIPcopy(scip, subscip, varmap, NULL, "__boundwriting", TRUE, FALSE, TRUE, &valid) ); if( valid ) { SCIP_VAR** branchvars; SCIP_Real* branchbounds; SCIP_BOUNDTYPE* boundtypes; int nbranchvars; int size; size = SCIPnodeGetDepth(node); /* allocate memory for all branching decisions */ SCIP_CALL( SCIPallocBufferArray(scip, &branchvars, size) ); SCIP_CALL( SCIPallocBufferArray(scip, &branchbounds, size) ); SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, size) ); /* we assume that we only have one branching decision at each node */ SCIPnodeGetAncestorBranchings( node, branchvars, branchbounds, boundtypes, &nbranchvars, size ); /* check if did not have enough memory */ if( nbranchvars > size ) { size = nbranchvars; SCIP_CALL( SCIPallocBufferArray(scip, &branchvars, size) ); SCIP_CALL( SCIPallocBufferArray(scip, &branchbounds, size) ); SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, size) ); /* now getting all information */ SCIPnodeGetAncestorBranchings( node, branchvars, branchbounds, boundtypes, &nbranchvars, size ); } /* apply all changes to the submip */ SCIP_CALL( applyDomainChanges(subscip, branchvars, branchbounds, boundtypes, nbranchvars, varmap) ); /* free memory for all branching decisions */ SCIPfreeBufferArray(scip, &boundtypes); SCIPfreeBufferArray(scip, &branchbounds); SCIPfreeBufferArray(scip, &branchvars); /* do not abort subproblem on CTRL-C */ SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) ); /* disable output to console */ SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) ); /* solve only root node */ SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", 1LL) ); /* set cutoffbound as objective limit for subscip */ SCIP_CALL( SCIPsetObjlimit(subscip, SCIPgetCutoffbound(scip)) ); SCIP_CALL( SCIPsolve(subscip) ); cutoff = (SCIPgetStatus(subscip) == SCIP_STATUS_INFEASIBLE); submipdb = SCIPgetDualbound(subscip) * SCIPgetTransObjscale(scip) + SCIPgetTransObjoffset(scip); } #ifdef LONGSTATS SCIPinfoMessage(scip, file, "Node %"SCIP_LONGINT_FORMAT" (depth %d): dualbound: %g, nodesubmiprootdualbound: %g %s\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node), submipdb, cutoff ? "(cutoff)" : ""); #else SCIPinfoMessage(scip, file, "%"SCIP_LONGINT_FORMAT" %d %g %g %s\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node), submipdb, cutoff ? "(cutoff)" : ""); #endif /* free hash map */ SCIPhashmapFree(&varmap); SCIP_CALL( SCIPfree(&subscip) ); } else { #ifdef LONGSTATS SCIPinfoMessage(scip, file, "Node %"SCIP_LONGINT_FORMAT" (depth %d): dualbound: %g\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node)); #else SCIPinfoMessage(scip, file, "%"SCIP_LONGINT_FORMAT" %d %g\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node)); #endif } } } #ifdef LONGSTATS SCIPinfoMessage(scip, file, "\n"); #endif return SCIP_OKAY; }
/** call writing method */ static SCIP_RETCODE writeBoundsFocusNode( SCIP* scip, /**< SCIP data structure */ SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */ ) { FILE* file; SCIP_Bool writesubmipdualbound; SCIP_NODE* node; assert(scip != NULL); assert(eventhdlrdata != NULL); file = eventhdlrdata->file; writesubmipdualbound = eventhdlrdata->writesubmipdualbound; node = SCIPgetCurrentNode(scip); /* do not process probing nodes */ if( SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE ) return SCIP_OKAY; /* do not process cutoff nodes */ if( SCIPisInfinity(scip, SCIPgetNodeDualbound(scip, node)) ) return SCIP_OKAY; if( !SCIPisEQ(scip, eventhdlrdata->lastpb, SCIPgetPrimalbound(scip)) ) { #ifdef LONGSTATS SCIPinfoMessage(scip, file, "Status after %"SCIP_LONGINT_FORMAT" processed nodes (%d open)\n", SCIPgetNNodes(scip), SCIPgetNNodesLeft(scip)); SCIPinfoMessage(scip, file, "Primalbound: %g\n", SCIPgetPrimalbound(scip)); SCIPinfoMessage(scip, file, "Dualbound: %g\n", SCIPgetDualbound(scip)); #else SCIPinfoMessage(scip, file, "PB %g\n", SCIPgetPrimalbound(scip)); #endif eventhdlrdata->lastpb = SCIPgetPrimalbound(scip); } if( writesubmipdualbound ) { SCIP* subscip; SCIP_Bool valid; SCIP_Real submipdb; SCIP_Bool cutoff; SCIP_CALL( SCIPcreate(&subscip) ); submipdb = SCIP_INVALID; valid = FALSE; cutoff = FALSE; SCIP_CALL( SCIPcopy(scip, subscip, NULL, NULL, "__boundwriting", FALSE, FALSE, TRUE, &valid) ); if( valid ) { /* do not abort subproblem on CTRL-C */ SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) ); /* disable output to console */ SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) ); /* solve only root node */ SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", 1LL) ); #if 0 /* disable heuristics in subscip */ SCIP_CALL( SCIPsetHeuristics(subscip, SCIP_PARAMSETTING_OFF, TRUE) ); #endif /* set cutoffbound as objective limit for subscip */ SCIP_CALL( SCIPsetObjlimit(subscip, SCIPgetCutoffbound(scip)) ); SCIP_CALL( SCIPsolve(subscip) ); cutoff = (SCIPgetStatus(subscip) == SCIP_STATUS_INFEASIBLE); submipdb = SCIPgetDualbound(subscip) * SCIPgetTransObjscale(scip) + SCIPgetTransObjoffset(scip); } #ifdef LONGSTATS SCIPinfoMessage(scip, file, "Node %"SCIP_LONGINT_FORMAT" (depth %d): dualbound: %g, nodesubmiprootdualbound: %g %s\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node), submipdb, cutoff ? "(cutoff)" : ""); #else SCIPinfoMessage(scip, file, "%"SCIP_LONGINT_FORMAT" %d %g %g %s\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node), submipdb, cutoff ? "(cutoff)" : ""); #endif SCIP_CALL( SCIPfree(&subscip) ); } else { #ifdef LONGSTATS SCIPinfoMessage(scip, file, "Node %"SCIP_LONGINT_FORMAT" (depth %d): dualbound: %g\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node)); #else SCIPinfoMessage(scip, file, "%"SCIP_LONGINT_FORMAT" %d %g\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node)); #endif } #ifdef LONGSTATS SCIPinfoMessage(scip, file, "\n"); #endif return SCIP_OKAY; }