35#include "scip/debug.h"
39#if SCIP_APIVERSION >= 101
50 assert(nodesel != NULL);
51 assert(strcmp(SCIPnodeselGetName(nodesel),
"ScipParaObjSelfSplitNodeSel") == 0);
53 assert(selnode != NULL);
60 node = SCIPgetBestNode(scip);
67 if( SCIPnodeGetDepth(node) > depthlimit )
83 SCIP_CALL( SCIPgetOpenNodesData(scip, &leaves, &children, &siblings, &nleaves, &nchildren, &nsiblings) );
84 nnodes = nleaves + nchildren + nsiblings;
85 assert(nnodes == SCIPgetNNodesLeft(scip));
89 SCIP_CALL( SCIPallocMemoryArray(scip, &nodes, nnodes) );
90 SCIP_CALL( SCIPallocMemoryArray(scip, &depths, nnodes) );
92 for(i = 0; i < nchildren; i++)
94 nodes[i] = children[i];
95 depths[i] = SCIPnodeGetDepth(children[i]);
98 for(i = nchildren; i < nchildren+nsiblings; i++)
100 nodes[i] = siblings[i-nchildren];
101 depths[i] = SCIPnodeGetDepth(siblings[i-nchildren]);
104 offset = nchildren+nsiblings;
105 for(i = offset; i < nnodes; i++)
107 nodes[i] = leaves[i-offset];
108 depths[i] = SCIPnodeGetDepth(leaves[i-offset]);
111 SCIPsortIntPtr(depths, (
void**)nodes, nnodes);
113 for(i = 0; i < nnodes; i++)
115 if( (i % selfsplitsize) == selfsplitrank )
117 keepParaNode( scip, depths[i], nodes[i] );
119 SCIP_CALL( SCIPcutoffNode(scip,nodes[i]));
122 SCIP_CALL( SCIPpruneTree(scip) );
123 assert( SCIPgetNNodesLeft(scip) == 0 );
125 SCIPfreeMemoryArray(scip, &depths);
126 SCIPfreeMemoryArray(scip, &nodes);
135 *selnode = SCIPgetBestSibling(scip);
136 if( *selnode == NULL )
138 *selnode = SCIPgetBestLeaf(scip);
139 if( *selnode == NULL )
140 *selnode=SCIPgetBestChild(scip);
142 if( *selnode != NULL )
144 SCIPdebugMessage(
"Selecting next node number %" SCIP_LONGINT_FORMAT
" at depth %d\n", SCIPnodeGetNumber(*selnode), SCIPnodeGetDepth(*selnode));
150 if( *selnode == NULL )
152 *selnode = SCIPgetBestNode(scip);
170 depth1 = SCIPnodeGetDepth(node1);
171 depth2 = SCIPnodeGetDepth(node2);
174 if( depth1 < depth2 )
176 else if( depth1 > depth2 )
181 SCIP_Longint number1;
182 SCIP_Longint number2;
184 number1 = SCIPnodeGetNumber(node1);
185 number2 = SCIPnodeGetNumber(node2);
186 assert(number1 != number2);
188 if( number1 < number2 )
200 estimate1 = SCIPnodeGetEstimate(node1);
201 estimate2 = SCIPnodeGetEstimate(node2);
202 if( (SCIPisInfinity(scip, estimate1) && SCIPisInfinity(scip, estimate2)) ||
203 (SCIPisInfinity(scip, -estimate1) && SCIPisInfinity(scip, -estimate2)) ||
204 SCIPisEQ(scip, estimate1, estimate2) )
206 SCIP_Real lowerbound1;
207 SCIP_Real lowerbound2;
209 lowerbound1 = SCIPnodeGetLowerbound(node1);
210 lowerbound2 = SCIPnodeGetLowerbound(node2);
211 if( SCIPisLT(scip, lowerbound1, lowerbound2) )
213 else if( SCIPisGT(scip, lowerbound1, lowerbound2) )
217 SCIP_NODETYPE nodetype1;
218 SCIP_NODETYPE nodetype2;
220 nodetype1 = SCIPnodeGetType(node1);
221 nodetype2 = SCIPnodeGetType(node2);
222 if( nodetype1 == SCIP_NODETYPE_CHILD && nodetype2 != SCIP_NODETYPE_CHILD )
224 else if( nodetype1 != SCIP_NODETYPE_CHILD && nodetype2 == SCIP_NODETYPE_CHILD )
226 else if( nodetype1 == SCIP_NODETYPE_SIBLING && nodetype2 != SCIP_NODETYPE_SIBLING )
228 else if( nodetype1 != SCIP_NODETYPE_SIBLING && nodetype2 == SCIP_NODETYPE_SIBLING )
234 depth1 = SCIPnodeGetDepth(node1);
235 depth2 = SCIPnodeGetDepth(node2);
236 if( depth1 < depth2 )
238 else if( depth1 > depth2 )
246 if( SCIPisLT(scip, estimate1, estimate2) )
249 assert(SCIPisGT(scip, estimate1, estimate2));
255ScipParaObjSelfSplitNodesel::keepParaNode(
261 assert( depth == SCIPnodeGetDepth( node ) );
262 SCIP_VAR **branchVars =
new SCIP_VAR*[depth];
263 SCIP_Real *branchBounds =
new SCIP_Real[depth];
264 SCIP_BOUNDTYPE *boundTypes =
new SCIP_BOUNDTYPE[depth];
266 SCIPnodeGetAncestorBranchings( node, branchVars, branchBounds, boundTypes, &nBranchVars, depth );
267 if( nBranchVars > depth )
269 delete [] branchVars;
270 delete [] branchBounds;
271 delete [] boundTypes;
272 branchVars =
new SCIP_VAR*[nBranchVars];
273 branchBounds =
new SCIP_Real[nBranchVars];
274 boundTypes =
new SCIP_BOUNDTYPE[nBranchVars];
275 SCIPnodeGetAncestorBranchings( node, branchVars, branchBounds, boundTypes, &nBranchVars, nBranchVars );
278 int nVars = SCIPgetNVars(scip);
280 int *iBranchVars =
new int[nBranchVars];
282 SCIP_HASHMAP* varmapLb;
283 SCIP_HASHMAP* varmapUb;
284 SCIP_CALL_ABORT( SCIPhashmapCreate(&varmapLb, SCIPblkmem(scip), nVars) );
285 SCIP_CALL_ABORT( SCIPhashmapCreate(&varmapUb, SCIPblkmem(scip), nVars) );
286 for(
int i = 0; i < nBranchVars; i++ )
289 if( boundTypes[i] == SCIP_BOUNDTYPE_LOWER )
291 if( !SCIPhashmapGetImage(varmapLb, branchVars[i]) )
293 SCIP_CALL_ABORT( SCIPhashmapInsert(varmapLb, branchVars[i], &iBranchVars[i] ) );
298 if( !SCIPhashmapGetImage(varmapUb, branchVars[i]) )
300 SCIP_CALL_ABORT( SCIPhashmapInsert(varmapUb, branchVars[i], &iBranchVars[i] ) );
372 SCIPhashmapFree(&varmapLb);
373 SCIPhashmapFree(&varmapUb);
379 delete [] iBranchVars;
381 if( scipParaSolver->isCopyIncreasedVariables() )
383 if( !ifFeasibleInOriginalProblem(scip, nBranchVars, branchVars, branchBounds) )
385 delete [] branchVars;
386 delete [] branchBounds;
387 delete [] boundTypes;
392 SCIP_CONS** addedcons = 0;
393 int addedconsssize = SCIPnodeGetNAddedConss(node);
395 if( addedconsssize > 0 )
397 SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &addedcons, addedconsssize) );
398 SCIPnodeGetAddedConss(node, addedcons, &naddedconss, addedconsssize);
401 assert( scipParaSolver->getParentDiffSubproblem() == 0 );
417 SCIPfreeBufferArray(scip, &addedcons);
421 long long n = SCIPnodeGetNumber( node );
423 double dualBound = std::min(SCIPretransformObj(scip, SCIPnodeGetLowerbound( node )), SCIPgetDualbound(scip));
430 double estimateValue = SCIPnodeGetEstimate( node );
432#ifdef UG_DEBUG_SOLUTION
434 SCIP_CALL_ABORT( SCIPdebugSolIsValidInSubtree(scip, &valid) );
435 diffSubproblem->setOptimalSolIndicator(valid);
436 std::cout <<
"* R." << scipParaSolver->getRank() <<
", debug = " << SCIPdebugSolIsEnabled(scip) <<
", valid = " << valid << std::endl;
438 scipParaSolver->keepParaNode(n, depth, dualBound, estimateValue, diffSubproblem);
441#ifdef UG_DEBUG_SOLUTION
444 SCIPdebugSolDisable(scip);
445 std::cout <<
"R." << paraComm->getRank() <<
": disable debug, node which contains optmal solution is sent." << std::endl;
449 delete [] branchVars;
450 delete [] branchBounds;
451 delete [] boundTypes;
456ScipParaObjSelfSplitNodesel::ifFeasibleInOriginalProblem(
459 SCIP_VAR **branchVars,
460 SCIP_Real *inBranchBounds)
463 bool feasible =
true;
464 SCIP_Real *branchBounds =
new SCIP_Real[nBranchVars];
465 for(
int v = nBranchVars -1 ; v >= 0; --v )
467 SCIP_VAR *transformVar = branchVars[v];
468 SCIP_Real scalar = 1.0;
469 SCIP_Real constant = 0.0;
470 SCIP_CALL_ABORT( SCIPvarGetOrigvarSum(&transformVar, &scalar, &constant ) );
471 if( transformVar == NULL )
continue;
473 branchBounds[v] = ( inBranchBounds[v] - constant ) / scalar;
474 if( SCIPvarGetType(transformVar) != SCIP_VARTYPE_CONTINUOUS
475 && SCIPvarGetProbindex(transformVar) < scipParaSolver->getNOrgVars() )
477 if( !(SCIPisLE(scip,scipParaSolver->getOrgVarLb(SCIPvarGetProbindex(transformVar)), branchBounds[v]) &&
478 SCIPisGE(scip,scipParaSolver->getOrgVarUb(SCIPvarGetProbindex(transformVar)), branchBounds[v])) )
485 delete [] branchBounds;
Base class of communicator for UG Framework.
#define DEF_SCIP_PARA_COMM(scip_para_comm, comm)
SCIP_DECL_NODESELSELECT(ScipParaObjNodesel::scip_select)
SCIP_DECL_NODESELCOMP(ScipParaObjNodesel::scip_comp)
node selector for self-split ramp-up