/** node selection method of node selector */ static SCIP_DECL_NODESELSELECT(nodeselSelectMaster) { SCIP_NODESELDATA* nodeseldata; SCIP_NODE** nodes; SCIP_CONS* origcons; SCIP_CONS* parentorigcons; SCIP_CONS* parentmastercons; SCIP* origscip; int nnodes; SCIP_Longint orignodenumber; assert(nodesel != NULL); assert(strcmp(SCIPnodeselGetName(nodesel), NODESEL_NAME) == 0); assert(scip != NULL); assert(selnode != NULL); nodeseldata = SCIPnodeselGetData(nodesel); assert(nodeseldata != NULL); origscip = GCGpricerGetOrigprob(scip); *selnode = NULL; orignodenumber = SCIPnodeGetNumber(SCIPgetCurrentNode(origscip)); if( orignodenumber != nodeseldata->lastorignodenumber ) { nodeseldata->lastorignodenumber = orignodenumber; origcons = GCGconsOrigbranchGetActiveCons(origscip); parentorigcons = GCGconsOrigbranchGetParentcons(origcons); /* check whether the current node is the root node and has no parent */ if( parentorigcons == NULL ) { assert((GCGconsOrigbranchGetNode(origcons) == SCIPgetRootNode(origscip)) || ( GCGconsOrigbranchGetNode(origcons) == NULL) ); assert(GCGconsOrigbranchGetMastercons(origcons) != NULL); assert((GCGconsMasterbranchGetNode(GCGconsOrigbranchGetMastercons(origcons)) == SCIPgetRootNode(scip)) || (GCGconsMasterbranchGetNode(GCGconsOrigbranchGetMastercons(origcons)) == NULL)); *selnode = SCIPgetRootNode(scip); SCIPdebugMessage("selected root node in the master program\n"); } else { parentmastercons = GCGconsOrigbranchGetMastercons(parentorigcons); assert(parentmastercons != NULL); assert( (GCGconsOrigbranchGetChild1cons(parentorigcons) == origcons) != (GCGconsOrigbranchGetChild2cons(parentorigcons) == origcons)); /* the original cons is the left child of its parentcons, select the left child of the corresponding parentcons in the master*/ if( GCGconsOrigbranchGetChild1cons(parentorigcons) == origcons ) { assert(GCGconsMasterbranchGetChild1cons(parentmastercons) != NULL); assert(GCGconsMasterbranchGetNode(GCGconsMasterbranchGetChild1cons(parentmastercons)) != NULL); *selnode = GCGconsMasterbranchGetNode(GCGconsMasterbranchGetChild1cons(parentmastercons)); SCIPdebugMessage("Master nodeselector selected node %"SCIP_LONGINT_FORMAT" corresponding to node %"SCIP_LONGINT_FORMAT" in the original program, since the parents (%"SCIP_LONGINT_FORMAT"/o, %"SCIP_LONGINT_FORMAT"/m) are linked\n", SCIPnodeGetNumber(*selnode), SCIPnodeGetNumber(GCGconsOrigbranchGetNode(origcons)), SCIPnodeGetNumber(GCGconsOrigbranchGetNode(parentorigcons)), SCIPnodeGetNumber(GCGconsMasterbranchGetNode(parentmastercons))); } /* the original cons is the right child of its parentcons, select the right child of the corresponding parentcons in the master */ else { assert(GCGconsOrigbranchGetChild2cons(parentorigcons) == origcons); assert(GCGconsMasterbranchGetChild2cons(parentmastercons) != NULL); assert(GCGconsMasterbranchGetNode(GCGconsMasterbranchGetChild2cons(parentmastercons)) != NULL); *selnode = GCGconsMasterbranchGetNode(GCGconsMasterbranchGetChild2cons(parentmastercons)); SCIPdebugMessage("Master nodeselector selected node %"SCIP_LONGINT_FORMAT" corresponding to node %"SCIP_LONGINT_FORMAT" in the original program, since the parents (%"SCIP_LONGINT_FORMAT"/o, %"SCIP_LONGINT_FORMAT"/m) are linked\n", SCIPnodeGetNumber(*selnode), SCIPnodeGetNumber(GCGconsOrigbranchGetNode(origcons)), SCIPnodeGetNumber(GCGconsOrigbranchGetNode(parentorigcons)), SCIPnodeGetNumber(GCGconsMasterbranchGetNode(parentmastercons))); } } if( *selnode == NULL ) { SCIPerrorMessage("nodesel_master could not find a node corresponding to the current original node!\n"); } assert(*selnode != NULL); /* set the dual bound to the lower bound of the corresponding original node */ SCIP_CALL( SCIPupdateNodeDualbound(scip, *selnode, SCIPgetNodeLowerbound(origscip, SCIPgetCurrentNode(origscip))) ); } else { SCIPdebugMessage("select random node\n"); if( SCIPgetNChildren(scip) > 0 ) { SCIP_CALL( SCIPgetChildren(scip, &nodes, &nnodes) ); *selnode = nodes[0]; } else if( SCIPgetNSiblings(scip) > 0 ) { SCIP_CALL( SCIPgetSiblings(scip, &nodes, &nnodes) ); *selnode = nodes[0]; } else if( SCIPgetNLeaves(scip) > 0 ) { SCIP_CALL( SCIPgetLeaves(scip, &nodes, &nnodes) ); *selnode = nodes[0]; } } #ifndef NDEBUG GCGconsOrigbranchCheckConsistency(origscip); GCGconsMasterbranchCheckConsistency(scip); #endif 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; }