Ejemplo n.º 1
0
/** adds initial constraint to root node */
SCIP_RETCODE SCIPconsOrigbranchAddRootCons(
   SCIP*                 scip                /**< SCIP data structure */
   )
{
   SCIP_CONSHDLR* conshdlr;
   SCIP_CONSHDLRDATA* conshdlrdata;
   SCIP_CONS* cons;
   assert(scip != NULL);

   conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
   if( conshdlr == NULL )
   {
      SCIPerrorMessage("origbranch constraint handler not found\n");
      return SCIP_ERROR;
   }

   conshdlrdata = SCIPconshdlrGetData(conshdlr);
   assert(conshdlrdata != NULL);
   if( conshdlrdata->rootcons == NULL )
   {
      SCIP_CALL( GCGcreateConsOrigbranch(scip, &cons, "root-origbranch", NULL, NULL, NULL, NULL) );

      SCIP_CALL( SCIPaddConsNode(scip, SCIPgetRootNode(scip), cons, SCIPgetRootNode(scip)) );
      conshdlrdata->rootcons = cons;
   }

   /* check consistency */
   GCGconsOrigbranchCheckConsistency(scip);

   return SCIP_OKAY;
}
Ejemplo n.º 2
0
/** branching execution method for fractional LP solutions */
static
SCIP_DECL_BRANCHEXECLP(branchExeclpnodereopt)
{/*lint --e{715}*/
   assert(branchrule != NULL );
   assert(*result != SCIP_BRANCHED);

   *result = SCIP_DIDNOTRUN;

   if( SCIPisReoptEnabled(scip) && SCIPreoptimizeNode(scip, SCIPgetCurrentNode(scip)) )
   {
      SCIP_VAR** branchcands;
      SCIP_Real* branchcandssol;
      SCIP_Real* branchcandsfrac;
      int nbranchcands;

      SCIP_Bool sbinit;
      SCIP_Real objsimrootlp;

      SCIP_CALL( SCIPgetBoolParam(scip, "reoptimization/strongbranchinginit", &sbinit) );
      SCIP_CALL( SCIPgetRealParam(scip, "reoptimization/objsimrootLP", &objsimrootlp) );

      if( sbinit && SCIPgetCurrentNode(scip) == SCIPgetRootNode(scip)
       && SCIPgetReoptSimilarity(scip, SCIPgetNReoptRuns(scip), SCIPgetNReoptRuns(scip)) <= objsimrootlp ) /* check objsimrootlp */
      {
         /* get branching candidates */
         SCIP_CALL( SCIPgetLPBranchCands(scip, &branchcands, &branchcandssol, &branchcandsfrac, NULL, &nbranchcands, NULL) );

         /* run strong branching initialization */
         if( nbranchcands > 0 )
         {
            SCIP_CALL( SCIPexecRelpscostBranching(scip, TRUE, branchcands, branchcandssol, branchcandsfrac, nbranchcands, FALSE, result) );
            assert(*result == SCIP_DIDNOTRUN || *result == SCIP_CUTOFF || *result == SCIP_REDUCEDDOM);
         }
      }

      if( *result != SCIP_CUTOFF && *result != SCIP_REDUCEDDOM)
      {
         assert((SCIPnodeGetReoptID(SCIPgetCurrentNode(scip)) == 0 && SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0 )
              || 1 <= SCIPnodeGetReoptID(SCIPgetCurrentNode(scip)));

         SCIP_CALL( Exec(scip, result) );
      }
   }

   return SCIP_OKAY;
}
Ejemplo n.º 3
0
/** constraint activation notification method of constraint handler */
static
SCIP_DECL_CONSACTIVE(consActiveOrigbranch)
{  /*lint --e{715}*/
   SCIP_CONSHDLRDATA* conshdlrData;

   assert(scip != NULL);
   assert(conshdlr != NULL);
   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
   assert(cons != NULL);

   conshdlrData = SCIPconshdlrGetData(conshdlr);
   assert(conshdlrData != NULL);
   assert(conshdlrData->stack != NULL);

   assert(SCIPconsGetData(cons) != NULL);

   if( SCIPconsGetData(cons)->node == NULL )
      SCIPconsGetData(cons)->node = SCIPgetRootNode(scip);

   SCIPdebugMessage("Activating branch orig constraint: <%s>[stack size: %d].\n", SCIPconsGetName(cons),
      conshdlrData->nstack+1);

   /* put constraint on the stack */
   if( conshdlrData->nstack >= conshdlrData->maxstacksize )
   {
      SCIP_CALL( SCIPreallocMemoryArray(scip, &(conshdlrData->stack), 2*(conshdlrData->maxstacksize)) );
      conshdlrData->maxstacksize = 2*(conshdlrData->maxstacksize);
      SCIPdebugMessage("reallocating Memory for stack! %d --> %d\n", conshdlrData->maxstacksize/2, conshdlrData->maxstacksize);
   }

   /* put constraint on the stack */
   assert(conshdlrData->stack != NULL);
   conshdlrData->stack[conshdlrData->nstack] = cons;
   ++(conshdlrData->nstack);

   return SCIP_OKAY;
}
Ejemplo n.º 4
0
/** 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;
}
Ejemplo n.º 5
0
/** Execute the branching of nodes with additional constraints. */
static
SCIP_RETCODE Exec(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_RESULT*          result              /**< pointer to store the result */
)
{
   SCIP_REOPTNODE* reoptnode;
   SCIP_NODE* curnode;
   SCIP_REOPTTYPE reopttype;
   SCIP_Bool localrestart;
   unsigned int* childids;
   unsigned int curid;
   int naddedconss;
   int nchilds;
   int childnodessize;
   int ncreatednodes;
   int c;


   assert(scip != NULL );
   assert(SCIPisReoptEnabled(scip));

   curnode = SCIPgetCurrentNode(scip);
   assert(curnode != NULL);

   curid = SCIPnodeGetReoptID(curnode);
   assert(curid >= 1 || SCIPgetRootNode(scip) == curnode);

   /* calculate local similarity and delete the induced subtree if the similarity is to low */
   localrestart = FALSE;
   SCIP_CALL( SCIPcheckReoptRestart(scip, curnode, &localrestart) );

   ncreatednodes = 0;

   if( localrestart )
   {
      *result = SCIP_DIDNOTRUN;
      goto TERMINATE;
   }

   SCIPdebugMessage("current node is %lld, ID %u:\n", SCIPnodeGetNumber(curnode), curid);

   /* get the corresponding node of the reoptimization tree */
   reoptnode = SCIPgetReoptnode(scip, curid);
   assert(reoptnode != NULL);
   reopttype = (SCIP_REOPTTYPE)SCIPreoptnodeGetType(reoptnode);


   /* The current node is equal to the root and dual reductions were performed. Since the root has a special role
    * within the reoptimiziation we have to split the root node into several nodes and move all stored child nodes to
    * the one representing the root node including all dual reductions as before.
    *
    * @note If the type is infsubtree, there cannot exist a child node and the method SCIPapplyReopt adds a global valid
    * constraint only.
    */
   if( curid == 0 )
   {
      if( reopttype == SCIP_REOPTTYPE_STRBRANCHED || reopttype == SCIP_REOPTTYPE_INFSUBTREE )
      {
         int ncreatedchilds;

         /* apply the reoptimization at the root node */
         SCIP_CALL( SCIPsplitReoptRoot(scip, &ncreatedchilds, &naddedconss) );

         if( reopttype == SCIP_REOPTTYPE_INFSUBTREE )
         {
            assert(ncreatedchilds == 0);
            assert(naddedconss == 1);

            /* there is nothing to do */
            *result = SCIP_DIDNOTRUN;

            goto TERMINATE;
         }

         assert(reopttype == SCIP_REOPTTYPE_STRBRANCHED);
         assert(ncreatedchilds >= 2);

         ncreatednodes += ncreatedchilds;

         /* We decrease the counter by one because after splitting the root node and moving all children to the node
          * representing the original root with all fixings (caused by dual reductions), we continue reactivating the
          * original children nodes of the root. Thus, the node containing all the fixings can be replaced by the children
          * nodes
          */
         --ncreatednodes;
      }

      goto REVIVE;
   }

   /* if we reach this part of the code the current has to be different to the root node */
   assert(curid >= 1);

  REVIVE:

   /* get the IDs of all child nodes */
   childnodessize = SCIPreoptnodeGetNChildren(reoptnode);
   SCIP_CALL( SCIPallocBufferArray(scip, &childids, childnodessize) );
   SCIP_CALL( SCIPgetReoptChildIDs(scip, curnode, childids, childnodessize, &nchilds) );

   if( childnodessize < nchilds )
   {
      childnodessize = SCIPreoptnodeGetNChildren(reoptnode);
      SCIP_CALL( SCIPreallocBufferArray(scip, &childids, childnodessize) );
      SCIP_CALL( SCIPgetReoptChildIDs(scip, curnode, childids, childnodessize, &nchilds) );
   }
   assert(nchilds <= childnodessize);

   naddedconss = 0;

   for(c = 0; c < nchilds; c++)
   {
      SCIP_NODE** childnodes;
      SCIP_Bool success;
      unsigned int childid;
      int ncreatedchilds;

      childid = childids[c];
      assert(childid >= 1);

      SCIPdebugMessage("process child at ID %u\n", childid);

      reoptnode = SCIPgetReoptnode(scip, childid);
      assert(reoptnode != NULL);

      reopttype = (SCIP_REOPTTYPE)SCIPreoptnodeGetType(reoptnode);
      ncreatedchilds = 0;

      /* check whether node need to be split */
      if( reopttype == SCIP_REOPTTYPE_STRBRANCHED || reopttype == SCIP_REOPTTYPE_INFSUBTREE )
      {
         /* by default we assume the node get split into two node (because using a constraint to split the node is
          * the default case
          */
         childnodessize = 2;
      }
      else
      {
         /* we only need to reconstruct the node */
         childnodessize = 1;
      }

      /* allocate buffer */
      SCIP_CALL( SCIPallocBufferArray(scip, &childnodes, childnodessize) );

      /* apply the reoptimization */
      SCIP_CALL( SCIPapplyReopt(scip, reoptnode, childid, SCIPnodeGetEstimate(curnode), childnodes, &ncreatedchilds,
            &naddedconss, childnodessize, &success) );

      if( !success )
      {
         assert(ncreatedchilds > childnodessize);

         /* reallocate buffer memory */
         childnodessize = ncreatedchilds+1;
         SCIP_CALL( SCIPreallocBufferArray(scip, &childnodes, childnodessize) );

         /* apply the reoptimization */
         SCIP_CALL( SCIPapplyReopt(scip, reoptnode, childid, SCIPnodeGetEstimate(curnode), childnodes, &ncreatedchilds,
               &naddedconss, childnodessize, &success) );
      }

      assert(success);

      /* free buffer memory */
      SCIPfreeBufferArray(scip, &childnodes);

      ncreatednodes += ncreatedchilds;
   }

   if( ncreatednodes == 0 )
      *result = SCIP_DIDNOTRUN;
   else
      *result = SCIP_BRANCHED;

   /* free the buffer memory */
   SCIPfreeBufferArray(scip, &childids);

  TERMINATE:

   SCIPdebugMessage("**** finish reoptimizing %d child nodes of node %lld ****\n", ncreatednodes, SCIPnodeGetNumber(curnode));

   return SCIP_OKAY;
}